CopyOnWriteArrayList 未按预期工作
CopyOnWriteArrayList is not working as expected
我在 CopyOnWriteArrayList 上学习,但它没有按照我的理解工作。
我有两个线程,一个是主线程,另一个是内线程。主线程正在从 CopyOnWriteArrayList 集合中删除对象,而内部线程正在休眠 5 秒。主线程在内部线程迭代之前完成删除操作,但内部线程仍在迭代整个集合,我的意思是哪些被主线程删除。
package com.kalavakuri.javaconcurrent;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentModificationExceptionExample {
private static List<String> strings = new CopyOnWriteArrayList<String>();
public static void main(String[] args) {
strings.add("Ram");
strings.add("Ravi");
strings.add("Raju");
strings.add("Raghu1");
strings.add("Raghu2");
strings.add("Raghu3");
strings.add("Raghu4");
strings.add("Raghu5");
strings.add("Raghu6");
Thread thread = new Thread(() -> {
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println("Thread name " + Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Inner thread");
thread.start();
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
String value = iterator.next();
strings.remove(value);
System.out.println("Thread name " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
strings.forEach(v -> System.out.println(v));
}
}
我希望内线程不应该迭代被主线程删除的对象。理解有误请指正
是的,你错了。来自 docs:
The "snapshot" style iterator method uses a reference to the state of
the array at the point that the iterator was created. This array never
changes during the lifetime of the iterator, so interference is
impossible and the iterator is guaranteed not to throw
ConcurrentModificationException.
因此,根据设计,迭代器不会在其他线程进行更改时更改。
我在 CopyOnWriteArrayList 上学习,但它没有按照我的理解工作。 我有两个线程,一个是主线程,另一个是内线程。主线程正在从 CopyOnWriteArrayList 集合中删除对象,而内部线程正在休眠 5 秒。主线程在内部线程迭代之前完成删除操作,但内部线程仍在迭代整个集合,我的意思是哪些被主线程删除。
package com.kalavakuri.javaconcurrent;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentModificationExceptionExample {
private static List<String> strings = new CopyOnWriteArrayList<String>();
public static void main(String[] args) {
strings.add("Ram");
strings.add("Ravi");
strings.add("Raju");
strings.add("Raghu1");
strings.add("Raghu2");
strings.add("Raghu3");
strings.add("Raghu4");
strings.add("Raghu5");
strings.add("Raghu6");
Thread thread = new Thread(() -> {
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println("Thread name " + Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Inner thread");
thread.start();
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
String value = iterator.next();
strings.remove(value);
System.out.println("Thread name " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
strings.forEach(v -> System.out.println(v));
}
}
我希望内线程不应该迭代被主线程删除的对象。理解有误请指正
是的,你错了。来自 docs:
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.
因此,根据设计,迭代器不会在其他线程进行更改时更改。