A simple one from http://www.ibm.com/developerworks/java/library/j-tiger06164.html.
import java.util.*;
import java.util.concurrent.*;
public class CopyOnWrite {
public static void main(String args[]) {
List list1 = new CopyOnWriteArrayList(Arrays.asList(args));
List list2 = new ArrayList(Arrays.asList(args));
Iterator itor1 = list1.iterator();
Iterator itor2 = list2.iterator();
list1.add("New");
list2.add("New");
try {
printAll(itor1);
} catch (ConcurrentModificationException e) {
System.err.println("Shouldn't get here");
}
try {
printAll(itor2);
} catch (ConcurrentModificationException e) {
System.err.println("Will get here.");
}
}
private static void printAll(Iterator itor) {
while (itor.hasNext()) {
System.out.println(itor.next());
}
}
}
A complex example using multiple threads.
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
public class MultiThreads {
public static void main(String[] args) throws Exception {
List<Val> ls = new CopyOnWriteArrayList<Val>();
ls.add(new Val(1, 10));
ls.add(new Val(2, 20));
ls.add(new Val(3, 30));
CountDownLatch latch = new CountDownLatch(1);
Walker w = new Walker(ls.iterator(), latch);
Modifer m = new Modifer(ls, latch);
w.start();
m.start();
latch.await();
System.out.println("===========");
Iterator<Val> it = ls.iterator();
while (it.hasNext())
System.out.println("[main] " + it.next());
}
}
class Walker extends Thread {
Iterator<Val> it;
CountDownLatch latch;
Walker(Iterator<Val> it, CountDownLatch latch) {
this.it = it;
this.latch = latch;
}
public void run() {
try {
latch.await();
System.out.println("===========");
while (it.hasNext())
System.out.println("[walker] " + it.next());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class Modifer extends Thread {
List<Val> ls;
CountDownLatch latch;
public Modifer(List<Val> ls, CountDownLatch latch) {
this.ls = ls;
this.latch = latch;
}
public void run() {
try {
ls.set(0, new Val(1, 100));
ls.remove(2);
ls.add(new Val(3, 300));
ls.add(new Val(4, 400));
latch.countDown();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class Val {
private int no;
private int age;
public Val(int no, int age) {
this.no = no;
this.age = age;
}
public String toString() {
return "no: " + no + ", age: " + age;
}
}