Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Generate random numbers concurrently – ThreadLocalRandom

farenda 2016-12-20 0

Until Java 7 there was no simple and effective way to generate random numbers concurrently. Here we show ThreadLocalRandom to generate random numbers in a thread-safe way.

One of the most notable additions in Java 7 was Fork Join Framework. But not many people know that it came with a bunch of classes useful in parallel computations. One of them is java.util.concurrent.ThreadLocalRandom. The class used in concurrent programs causes less overhead and contention than shared Random (which is not thread-safe as you probably know).

Thread safe random number generator

The usage of ThreadLocalRandom is pretty simple. We need to call current() static method to obtain a ThreadLocal version and then just obtain random numbers as usual. Here we use ints() from Java 8 to get stream of random ints and collect them into a List:

package com.farenda.java.util.concurrent;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import static java.util.stream.Collectors.toList;

public class ConcurrentRandomNumbers {

    public List<Integer> randomRange(int from, int howMany) {
        return ThreadLocalRandom.current()
                .ints(howMany, from, from+howMany)
                .boxed()
                .collect(toList());
    }
}

In the below program we’re going to use this method from concurrently executed tasks.

Generating random numbers in ranges

Task executed concurrently

Simple task that will request random numbers in range:

package com.farenda.java.util.concurrent;

import java.util.List;
import java.util.concurrent.Callable;

class ConcurrentRange implements Callable<List<Integer>> {

    private ConcurrentRandomNumbers generator;
    private final int from;
    private final int howMany;

    public ConcurrentRange(ConcurrentRandomNumbers generator,
                           int from, int howMany) {
        this.generator = generator;
        this.from = from;
        this.howMany = howMany;
    }

    @Override
    public List<Integer> call() throws Exception {
        // request random numbers for this thread:
        return generator.randomRange(from, howMany);
    }
}

Generate ranges of random numbers

We create three tasks to concurrently generate numbers in specified ranges and then just print the results:

package com.farenda.java.util.concurrent;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadLocalRandom;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

public class ConcurrentRandomNumbers {

    private List<Integer> randomRange(int from, int howMany) {
        return ThreadLocalRandom.current()
                .ints(howMany, from, from+howMany)
                .boxed()
                .collect(toList());
    }

    public static void main(String[] args) throws Exception {
        ConcurrentRandomNumbers generator = new ConcurrentRandomNumbers();

        ExecutorService es = Executors.newCachedThreadPool();

        List<ConcurrentRange> randomRanges = asList(
                new ConcurrentRange(generator, 10, 10),
                new ConcurrentRange(generator, 20, 10),
                new ConcurrentRange(generator, 30, 10));
        List<Future<List<Integer>>> results = es.invokeAll(randomRanges);

        for (Future<List<Integer>> future : results) {
            System.out.println("Range: " + future.get());
        }

        es.shutdown();
    }
}

Output of sample execution:

Range: [11, 16, 10, 10, 16, 13, 10, 11, 10, 18]
Range: [24, 25, 26, 22, 26, 26, 24, 29, 27, 24]
Range: [32, 30, 32, 30, 37, 31, 34, 30, 31, 36]

References:

  • Java random integers in range
  • Java ThreadLocal – thread data separation
Share with the World!
Categories Java Tags java, java-concurrency, java8
Previous: Insertion Sort in Clojure
Next: Clojure transients – fast mutations in persistent world

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2022

sponsored