public class CopyOnWriteArrayListTest {
private static class Worker implements Runnable {
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
// ConcurrentLinkedQueue list = new ConcurrentLinkedQueue();
private void run01() {
System.out.println(Thread.currentThread().getName() + " enter run01");
System.out.println("remove:" + list.remove(0));
}
private void run02() {
System.out.println(Thread.currentThread().getName() + " enter run02");
try {
list.add("A");
Thread.sleep(2000);
// System.out.println(“get:” + list.poll());
System.out.println(“get:” + list.get(0));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String name = Thread.currentThread().getName();
if (name.equals("1")) {
run01();
}
if (name.equals("2")) {
run02();
}
}
}
public static void main(String[] args) {
Worker work = new Worker();
Thread th1 = new Thread(work, "1");
Thread th2 = new Thread(work, "2");
th1.start();
th2.start();
System.out.println("end");
}
}
虽然CopyOnWriteArrayList适用于读大写小的场景,原因是读时无锁,写时有锁,但是其在并发读写时还是需要注意get时的ArrayIndexOutOfBoundsException错误,例子如上,此时会抛出以下异常:
Exception in thread “2” java.lang.ArrayIndexOutOfBoundsException: 0
at java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:368)
at java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:377)
at me.base.knowledge.sync.CopyOnWriteArrayListTest
Worker.run02(CopyOnWriteArrayListTest.java:29)atme.base.knowledge.sync.CopyOnWriteArrayListTest
Worker.run(CopyOnWriteArrayListTest.java:43)
at java.lang.Thread.run(Thread.java:745)
但是换用线程安全的ConcurrentLinkedQueue后,无异常抛出,但是也失去的高读性能。