Java 同步集合中的ConcurrentModificationException
我使用的是Java 同步集合中的ConcurrentModificationException,java,Java,我使用的是SynchronizedCollection.containsAll问题是,当我运行以下代码时,我遇到了ConcurrentModification异常 据我所知,代码应该毫无例外地终止 public class Main { public static void main(String[] args) { List l1 = new LinkedList(), l2 = new LinkedList(); for (int i = 0; i
SynchronizedCollection.containsAll
问题是,当我运行以下代码时,我遇到了ConcurrentModification异常
据我所知,代码应该毫无例外地终止
public class Main {
public static void main(String[] args) {
List l1 = new LinkedList(), l2 = new LinkedList();
for (int i = 0; i < 100000; i++) {
l1.add("" + i);
}
for (int i = 0; i < 100000; i++) {
l2.add("" + i);
}
// reverse to make the search take a little longer
Collections.reverse(l2);
final List sl1 = Collections.synchronizedList(l1);
final List sl2 = Collections.synchronizedList(l2);
new Thread() {
public void run() {
// synchronized (sl2) {
sl1.containsAll(sl2);
// }
}
}.start();
new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
sl2.add("3");
}
}.start();
}
}
公共类主{
公共静态void main(字符串[]args){
列表l1=新链接列表(),l2=新链接列表();
对于(int i=0;i<100000;i++){
l1.添加(“+i”);
}
对于(int i=0;i<100000;i++){
l2.添加(“+i”);
}
//反转以使搜索花费更长的时间
收藏。反面(l2);
最终列表sl1=Collections.synchronizedList(l1);
最终列表sl2=Collections.synchronizedList(l2);
新线程(){
公开募捐{
//已同步(sl2){
sl1.containsAll(sl2);
// }
}
}.start();
新线程(){
公开募捐{
试一试{
睡眠(100);
}捕捉(中断异常e){
}
sl2.添加(“3”);
}
}.start();
}
}
有人能帮我理解为什么会出现这种异常。根据
public class Main {
public static void main(String[] args) {
List l1 = new LinkedList(), l2 = new LinkedList();
for (int i = 0; i < 100000; i++) {
l1.add("" + i);
}
for (int i = 0; i < 100000; i++) {
l2.add("" + i);
}
// reverse to make the search take a little longer
Collections.reverse(l2);
final List sl1 = Collections.synchronizedList(l1);
final List sl2 = Collections.synchronizedList(l2);
new Thread() {
public void run() {
// synchronized (sl2) {
sl1.containsAll(sl2);
// }
}
}.start();
new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
sl2.add("3");
}
}.start();
}
}
用户在遍历返回的列表时,必须手动同步该列表
在您的示例中,当您运行sl.containsAll(sl2)
时,您迭代sl2
,而不在sl2
上同步。这无疑是containsAll
方法的一个实现细节,但是:
此实现迭代指定的集合,依次检查迭代器返回的每个元素,以查看它是否包含在此集合中
您可以通过在sl2
上同步来解决此问题(即,取消注释您已注释掉的代码)。我检查了代码,我认为存在异常,但如果当前代码
public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {return c.containsAll(coll);}
}
public boolean containsAll(集合coll){
已同步(互斥){返回c.containsAll(coll);}
}
已更改为
public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {
synchronized(coll) {
return c.containsAll(coll);}}
}
public boolean containsAll(集合coll){
已同步(互斥){
同步(coll){
返回c.containsAll(coll);}
}
然后问题就会解决。您读过Collections.synchronizedList()
的javadoc吗?为什么您认为sl1与sl2同步?而不是Thread.sleep(100)代码>将其更改为线程睡眠(1000)你会发现这很容易导致死锁,没有理由假设coll
是一个同步的集合。