Java – performance comparison test between threadlocalrandom and shared static random instances
•
Java
In our project for a task, we use static random instances to generate random numbers After the release of Java 7, a new threadlocalrandom class appeared to generate random numbers
From specification:
And:
So I did a little test:
public class ThreadLocalRandomTest { private static final int THREAD_COUNT = 100; private static final int GENERATED_NUMBER_COUNT = 1000; private static final int INT_RIGHT_BORDER = 5000; private static final int EXPERIMENTS_COUNT = 5000; public static void main(String[] args) throws InterruptedException { System.out.println("Number of threads: " + THREAD_COUNT); System.out.println("Length of generated numbers chain for each thread: " + GENERATED_NUMBER_COUNT); System.out.println("Right border integer: " + INT_RIGHT_BORDER); System.out.println("Count of experiments: " + EXPERIMENTS_COUNT); int repeats = 0; int workingTime = 0; long startTime = 0; long endTime = 0; for (int i = 0; i < EXPERIMENTS_COUNT; i++) { startTime = System.currentTimeMillis(); repeats += calculateRepeatsForSharedRandom(); endTime = System.currentTimeMillis(); workingTime += endTime - startTime; } System.out.println("Average repeats for shared Random instance: " + repeats / EXPERIMENTS_COUNT + ". Average working time: " + workingTime / EXPERIMENTS_COUNT + " ms."); repeats = 0; workingTime = 0; for (int i = 0; i < EXPERIMENTS_COUNT; i++) { startTime = System.currentTimeMillis(); repeats += calculateRepeatsForTheadLocalRandom(); endTime = System.currentTimeMillis(); workingTime += endTime - startTime; } System.out.println("Average repeats for ThreadLocalRandom: " + repeats / EXPERIMENTS_COUNT + ". Average working time: " + workingTime / EXPERIMENTS_COUNT + " ms."); } private static int calculateRepeatsForSharedRandom() throws InterruptedException { final Random rand = new Random(); final Map<Integer,Integer> counts = new HashMap<>(); for (int i = 0; i < THREAD_COUNT; i++) { Thread thread = new Thread() { @Override public void run() { for (int j = 0; j < GENERATED_NUMBER_COUNT; j++) { int random = rand.nextInt(INT_RIGHT_BORDER); if (!counts.containsKey(random)) { counts.put(random,0); } counts.put(random,counts.get(random) + 1); } } }; thread.start(); thread.join(); } int repeats = 0; for (Integer value : counts.values()) { if (value > 1) { repeats += value; } } return repeats; } private static int calculateRepeatsForTheadLocalRandom() throws InterruptedException { final Map<Integer,Integer> counts = new HashMap<>(); for (int i = 0; i < THREAD_COUNT; i++) { Thread thread = new Thread() { @Override public void run() { for (int j = 0; j < GENERATED_NUMBER_COUNT; j++) { int random = ThreadLocalRandom.current().nextInt(INT_RIGHT_BORDER); if (!counts.containsKey(random)) { counts.put(random,counts.get(random) + 1); } } }; thread.start(); thread.join(); } int repeats = 0; for (Integer value : counts.values()) { if (value > 1) { repeats += value; } } return repeats; }
}
I also added a non shared random test and got the next result:
Number of threads: 100 Length of generated numbers chain for each thread: 100 Right border integer: 5000 Count of experiments: 10000 Average repeats for non-shared Random instance: 8646. Average working time: 13 ms. Average repeats for shared Random instance: 8646. Average working time: 13 ms. Average repeats for ThreadLocalRandom: 8646. Average working time: 13 ms.
As for me, it's a little strange. I expect to be faster at least when using threadlocalrandom compared with the shared random instance, but it doesn't seem to make any difference
Someone can explain why it works, something I may not understand Thank you in advance
Solution
You are not running anything in parallel because you are waiting for each thread to complete immediately after startup You need a wait loop outside the loop to start the thread:
List<Thread> threads = new ArrayList<Thread>(); for (int i = 0; i < THREAD_COUNT; i++) { Thread thread = new Thread() { @Override public void run() { for (int j = 0; j < GENERATED_NUMBER_COUNT; j++) { int random = rand.nextInt(INT_RIGHT_BORDER); if (!counts.containsKey(random)) { counts.put(random,0); } counts.put(random,counts.get(random) + 1); } } }; threads.add(thread); thread.start(); } for (Thread thread: threads) { thread.join(); }
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码