我有以下代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyThread implements Runnable{
private List<Integer> myList;
public MyThread(List<Integer> list){
this.myList = list;
}
private void updateList(int i){
synchronized (myList) {
myList.add(i);
}
}
@Override
public void run() {
for( int i = 0; i < 1000000;i++){
updateList(i);
}
System.out.println("end: " + myList.size());
}
}
public class MyExecutor {
private List<Integer> taskList = new ArrayList<>();
private void launch(){
ExecutorService executorService= Executors.newFixedThreadPool(10000);
executorService.execute(new MyThread(taskList));
executorService.execute(new MyThread(taskList));
executorService.shutdown();
}
public static void main(String[] args) {
MyExecutor test = new MyExecutor();
test.launch();
}
}
输出应为: 2000000
我将得到不同的结果,这意味着这两个线程正在替换彼此的值。
我不知道问题出在哪里,对此代码进行了几次修改,但都没有解决问题。 (用Vector替换/在构造函数中添加了同步/在volatile中添加了
为什么此代码无法正常工作?
修改
在两个线程上,我都希望得到1000000
答案 0 :(得分:3)
输出应为:2000000
不,出于三个原因:
答案 1 :(得分:2)
你正在得到
end: 1065878
end: 2000000
第一行来自首先完成其工作的线程。它不应该完全是1M
,因为有多个线程正在工作。可以合理地假设,当第一个线程完成添加其1M
时,另一个线程至少添加了一个。
由于同步方法,第二行始终为2M
(如您所预期)。
我猜第一个线程应该以我想要的确切数目执行,不多也不少。
事情并行发生。线程正在运行。每个人都试图调用updateList
:一个人进入,其他人等待。没有人优先考虑下一个人,因此该方法的控制权以相当随机的方式传递给所有工人。
我敢打赌,您仍在考虑顺序执行:)一个线程运行整个run
方法,打印1M
,另一个线程获取一个1M大小的列表并添加其部分。
为了更好地理解它,请添加打印声明
private void updateList(int i) {
synchronized (myList) {
myList.add(i);
System.out.println(Thread.currentThread().getName() + " added " + i);
}
}
并减少要添加到任务的元素数量,例如10
。
pool-1-thread-1 added 0
pool-1-thread-1 added 1
pool-1-thread-1 added 2
pool-1-thread-1 added 3
pool-1-thread-2 added 0
pool-1-thread-2 added 1
pool-1-thread-2 added 2
pool-1-thread-2 added 3
pool-1-thread-1 added 4
pool-1-thread-1 added 5
pool-1-thread-1 added 6
pool-1-thread-1 added 7
pool-1-thread-1 added 8
pool-1-thread-1 added 9
end: 14
pool-1-thread-2 added 4
pool-1-thread-2 added 5
pool-1-thread-2 added 6
pool-1-thread-2 added 7
pool-1-thread-2 added 8
pool-1-thread-2 added 9
end: 20