测试代码:
package copyOnWriteArrayListTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class AddThread implements Runnable {
private List<Double> list;
public AddThread(List<Double> list) {
this.list = list;
}
public void run(){
for ( int i = 0; i < 10000; i++){
list.add(Math.random());
}
}
}
public class CopyOnWriteArrayListTest {
public static final int THREAD_POOL_SIZE = 2;
public static void main(String[] args) throws InterruptedException {
// List<Double> list = new ArrayList<>();
List<Double> list = new CopyOnWriteArrayList<>();
ExecutorService es = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
es.execute(new AddThread(list));
es.execute(new AddThread(list));
es.shutdown();
Thread.sleep(4000);
System.out.println("OK, list length: " + list.size());
}
}
输出结果:
OK, list length: 20000
如果把支持写时拷贝的list替换成普通的ArrayList:
List list = new ArrayList<>();
因为两个线程同时对这个普通的ArrayList进行写操作,结果如下:
OK, list length: 17578
看下CopyOnWriteArrayList实现源代码里Add方法的实现:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
lock初始化的地方:
final transient Object lock = new Object();