【发布时间】:2019-07-11 04:10:58
【问题描述】:
我正在尝试一个代码来看看如果一个线程修改一个集合而其他线程读取该集合会发生什么。这是代码
package threading;
import java.util.ArrayList;
public class ReadAndWrite {
static ArrayList<Integer> coll = new ArrayList<Integer>();
public static void main(String[] args) {
coll.add(1);
coll.add(3);
coll.add(5);
Thread t = new Thread() {
public void run(){
coll.add(2);
coll.add(6);
coll.add(8);
}
};
Thread t1 = new Thread() {
public void run(){
System.out.println(" collection is "+coll + " and size is "+coll.size());
}
};
Thread t2 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t3 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t4 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t5 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
t.start();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
当我首先开始写线程时,这是我一直得到的响应。
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
一旦我像下面这样更改顺序,事情就会变得混乱
t1.start();
t.start();
t2.start();
t3.start();
t4.start();
t5.start();
回应
collection is [1, 3, 5] and size is 3
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5] and size is 3
collection is [1, 3, 5] and size is 3
如果我们进一步尝试排序,我们会看到如下错误
Exception in thread "Thread-1" collection is [1, 3, 5, 2, 6, 8] and size is 6Exception in thread "Thread-2"
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at threading.ReadAndWrite$3.run(ReadAndWrite.java:28)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at threading.ReadAndWrite$2.run(ReadAndWrite.java:23)
问题:
- 同步或锁定在这里似乎是一个明显的解决方案,但为什么首先启动写入线程会给我们带来统一的结果,线程应该是乱序运行的不是吗?
- 我认为同时写入是一个问题,但即使我们只有一个写入线程,我们也会遇到错误,为什么?
将非常感谢有关上述方案的指导,在此先感谢。席德
【问题讨论】:
标签: java multithreading thread-safety