gpt4 book ai didi

java - ThreadLocalRandom与共享静态Random实例性能对比测试

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:27:28 25 4
gpt4 key购买 nike

在我们的一项任务项目中,我们使用静态随机实例作为随机数生成目标。 Java 7 发布后,出现了新的 ThreadLocalRandom 类,用于生成随机数。

来自规范:

When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention. Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools.

还有:

When all usages are of this form, it is never possible to accidently share a ThreadLocalRandom across multiple threads.

所以我做了我的小测试:

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, 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;
}

我还添加了非共享随机测试并得到了下一个结果:

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.

对我来说这有点奇怪,因为我预计与共享 Random 实例相比,使用 ThreadLocalRandom 至少会提高速度,但根本看不出有什么区别。

谁能解释一下为什么会这样,也许我没有正确测试。谢谢!

最佳答案

您没有并行运行任何东西,因为您正在等待每个线程在启动后立即完成。在启动线程的循环之外需要一个等待循环:

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();
}

关于java - ThreadLocalRandom与共享静态Random实例性能对比测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20265185/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com