Java例項學習 Java併發程式設計之java.util.concurrent.CopyOnWriteArrayList
CopyOnWriteArrayList
CopyOnWriteArrayList是ArrayList在併發環境下的替代品。CopyOnWriteArrayList通過增加寫時複製語義來避免併發訪問引起的問題,也就是說任何修改操作都會在底層建立一個列表的副本,也就意味著之前已有的迭代器不會碰到意料之外的修改。這種方式對於不要嚴格讀寫同步的場景非常有用,因為它提供了更好的效能。記住,要儘量減少鎖的使用,因為那勢必帶來效能的下降(對資料庫中資料的併發訪問不也是如此嗎?如果可以的話就應該放棄悲觀鎖而使用樂觀鎖),CopyOnWriteArrayList很明顯也是通過犧牲空間獲得了時間(在計算機的世界裡,時間和空間通常是不可調和的矛盾,可以犧牲空間來提升效率獲得時間,當然也可以通過犧牲時間來減少對空間的使用)。
舉例:
import java.util.ArrayList;
import java.util.List;
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;
}
@Override
public void run() {
for(int i = 0; i < 10000; ++i) {
list.add(Math.random());
}
}
}
public class Test05 {
private static final int THREAD_POOL_SIZE = 2;
public static void main(String[] args) {
List<Double> list = new ArrayList<>();
ExecutorService es = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
es.execute(new AddThread(list));
es.execute(new AddThread(list));
es.shutdown();
}
}
執行報錯:Exception in thread "pool-1-thread-1" java.lang.ArrayIndexOutOfBoundsException: 549
at java.util.ArrayList.add(ArrayList.java:459)
上面的程式碼會在執行時產生ArrayIndexOutOfBoundsException,
試一試將上面程式碼的ArrayList換成CopyOnWriteArrayList再重新執行。
List<Double> list = new CopyOnWriteArrayList<>();
- 1
- 1
執行不報錯
拓展:
public interface ExecutorService extends Executor {}
public interface Executor {}
public class Executors {}
轉載自:http://blog.csdn.net/jackfrued/article/details/44499227