1. 程式人生 > >Java例項學習 Java併發程式設計之java.util.concurrent.CopyOnWriteArrayList

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