【发布时间】:2020-06-30 11:22:39
【问题描述】:
我想在我的程序中实现多个线程。这多个线程应该能够处理一个数组。
例如:
我有一个整数数组:
int[] integerArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
现在,多个线程应该将每个项目打印到控制台,如下所示:
1 //Printed by Thread 1
2 //Printed by Thread 2
7 //Printed by Thread 1
8 //Printed by Thread 2
9 //Printed by Thread 3
4 //Printed by Thread 1
5 //Printed by Thread 2
6 //Printed by Thread 3
3 //Printed by Thread 3
10 //Printed by Thread 1
11 //Printed by Thread 2
12 //Printed by Thread 3
(结果是否随机无关紧要。)
到目前为止,我的解决方案是将数组拆分为更小的块。这是有效的,但我不太喜欢这个解决方案,我认为这不是真正的线程安全
public static void main(String[] args) {
int[] integerArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int chunk = 3;
for (int i = 0; i < integerArray.length; i += chunk) {
int finalI = i;
new Thread(() -> {
int[] splittedArray = Arrays.copyOfRange(integerArray, finalI, Math.min(integerArray.length, finalI + chunk));
for (int value : splittedArray) {
System.out.println(value);
}
}).start();
}
}
【问题讨论】:
-
您不需要拆分或复制数组,只需传递索引范围即可。您还可以为每个索引创建一个 Runnable,并将它们提交到由可配置数量的线程支持的 ExecutorService。还有
parallelStream:stackoverflow.com/questions/40933362/… -
“处理”数组涉及什么?例如,它是只读的还是数组在进程中被修改
-
@Thilo final 和 volatile 是完全独立的概念,无论如何都不能声明局部变量 volatile。我对你的意思有点困惑?
-
@matt:是的。挥发性在这里是无意义的。但是要使变量的更改对其他线程可见(例如这里启动的那些),对变量的访问需要以某种方式同步,它不会自动发生。 Final 和 volatile 已经这样做了,否则你必须自己做一些事情。在这个例子中没关系,因为 lambda 将获取(实际上是最终的)局部变量的副本。但总的来说,在线程之间传递数据之前需要考虑一下。
-
您能否解释一下为什么您不喜欢该解决方案以及为什么您认为它不是线程安全的?然后,我们可以比在答案或评论中推测更好地解决这些问题。
标签: java multithreading