【发布时间】:2019-06-28 20:02:13
【问题描述】:
总的来说,我是多线程的新手,所以我仍然不完全理解它。我不明白为什么我的代码有问题。我正在尝试使用前 1000 个数字填充 ArrayList,然后使用三个线程对所有数字求和。
public class Tst extends Thread {
private static int sum = 0;
private final int MOD = 3;
private final int compare;
private static final int LIMIT = 1000;
private static ArrayList<Integer> list = new ArrayList<Integer>();
public Tst(int compare){
this.compare=compare;
}
public synchronized void populate() throws InterruptedException{
for(int i=0; i<=Tst.LIMIT; i++){
if (i%this.MOD == this.compare){
list.add(i);
}
}
}
public synchronized void sum() throws InterruptedException{
for (Integer ger : list){
if (ger%MOD == this.compare){
sum+=ger;
}
}
}
@Override
public void run(){
try {
populate();
sum();
System.out.println(sum);
} catch (InterruptedException ex) {
Logger.getLogger(Tst.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
Tst tst1 = new Tst(0);
tst1.start();
Tst tst2 = new Tst(1);
tst2.start();
Tst tst3 = new Tst(2);
tst3.start();
}
}
我预计它会打印“500.500”,但它却打印了这个:
162241
328741
Exception in thread "Thread-0" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
at tst.Tst.sum(Tst.java:38)
at tst.Tst.run(Tst.java:50)
BUILD SUCCESSFUL (total time: 2 seconds)
【问题讨论】:
-
不相关:请在您的代码中使用有意义的(和可发音的)名称。 Tst ...没有任何意义。为什么不称它为 ListAccessThreadTester ... 或类似的名称。
-
您没有采取任何措施来阻止一个线程进入
sum()函数,而其他线程可能仍在populate()调用中。如果在for(Integer ger : list)循环运行时对列表进行了任何 更改,则会引发异常。不同的线程对列表的不同成员进行操作并不重要。 -
你的同步没用,因为每个线程都在自己同步。尝试将您的方法设为静态,您会发现不同。
标签: java multithreading synchronized