併發容器ConcurrentHashMap和CopyOnWriteArrayList

ConcurrentHashMap(用於替代HashMap)

    該類並非在每一個方法上加上同步鎖,而是使用分段鎖。迭代時不會拋出ConcurrentModificationException,因此不須要在迭代的時候,加上同步鎖 。不過在獲取size和isEmpty的時候,可能只是個估計值,而不是精確值。java

    一個ConcurrentHashMap由多個segment組成,每個segment都包含了一個HashEntry數組的hashtable, 每個segment包含了對本身的hashtable的操做,好比get,put,replace等操做,這些操做發生的時候,對本身的hashtable進行鎖定(分段鎖)。因爲每個segment寫操做只鎖定本身的hashtable,因此可能存在多個線程同時寫的狀況,性能無疑好於只有一個hashtable鎖定的狀況。數組

CopyOnWriteArrayList(用來替代同步List)

    迭代期間不須要加鎖。其基本思路是,從一開始你們都在共享同一個內容,當某我的想要修改這個內容的時候,纔會真正把內容Copy出去造成一個新的內容而後再改,這是一種延時懶惰策略。併發

   通俗的理解是當咱們往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行Copy,複製出一個新的容器,而後新的容器裏添加元素,添加完元素以後,再將原容器的引用指向新的容器。這樣作的好處是咱們能夠對CopyOnWrite容器進行併發的讀,而不須要加鎖,由於當前容器不會添加任何元素。因此CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不一樣的容器。下面是增長的時候的源碼:    性能

public boolean add(E e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}

    因爲添加元素的時候,會拷貝出一個副本再添加,所以這個list只適用於遍歷多,修改少的場景。this

相關文章
相關標籤/搜索