你好。请帮我解决以下问题:
使用 LongAccumulator 类计算最大和最小累加器。
假设应该有几个线程,生成元素的类型是任意的。这是我的代码:
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.LongAccumulator;
public class Main {
public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE);
public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE);
public static void main(String[] args){
Random random = new Random();
// Executor executor = Executors.newCachedThreadPool();
Executor executor = Executors.newFixedThreadPool(1);
for (int i = 1; i <= 1000; i++) {
int taskId = i;
Runnable task = () -> {
for (int k = 1; k <= 100_000; k++){
int value = random.nextInt(1_000_000);
maxValue.accumulate(value);
minValue.accumulate(value);
}
System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get());
};
executor.execute(task);
}
}
}
一切正常,但并不像我预期的那样。如果所有任务都放在一个线程中(见第 1 行Executor executor = Executors.newFixedThreadPool(1);),那么一切都会或多或少地完成。如果我们代替这一行Executor executor = Executors.newCachedThreadPool();,或放置多个线程:Executor executor = Executors.newFixedThreadPool(5);,那么代码运行时间会长几倍。实际上,问题在于为什么会出现这种情况,以及如何做到将任务划分为线程不会增加程序运行时间,而是会减少程序运行时间。
更新。按照评论中给出的建议,我将代码更改如下,程序开始在多线程模式下运行得更快:
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.LongAccumulator;
public class Main {
public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE);
public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE);
public static void main(String[] args){
Executor executor = Executors.newCachedThreadPool();
Runnable task; // вынес объявление из цикла ниже
for (int i = 1; i <= 1000; i++) {
Random random = new Random(); // для каждой задачи создаётся свой Random
int taskId = i;
task = () -> {
for (int k = 1; k <= 100_000; k++){
int value = random.nextInt(1_000_000);
maxValue.accumulate(value);
minValue.accumulate(value);
}
System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get());
};
executor.execute(task);
}
}
}
1 个回答