CopyOnWriteArrayList實現原理及源碼分析

  • 場景

         CopyOnWriteArrayList是Java併發包中提供的一個併發容器,它是個線程安全且讀操做無鎖的ArrayList,寫操做則經過建立底層數組的新副原本實現,是一種讀寫分離的併發策略,咱們也能夠稱這種容器爲"寫時複製器",Java併發包中相似的容器還有CopyOnWriteSet。數組

  • 實現原理 

         集合框架中的ArrayList是非線程安全的,Vector雖是線程安全的,但因爲簡單粗暴的鎖同步機制,性能較差。而CopyOnWriteArrayList則提供了另外一種不一樣的併發處理策略(固然是針對特定的併發場景)。安全

        不少時候,咱們的系統應對的都是讀多寫少的併發場景。CopyOnWriteArrayList容器容許併發讀,讀操做是無鎖的,性能較高。至於寫操做,好比向容器中添加一個元素,則首先將當前容器複製一份,而後在新副本上執行寫操做,結束以後再將原容器的引用指向新容器。併發

  • CopyOnWriteArrayList優勢分析

        讀操做性能很高,由於無需任何同步措施,比較適用於讀多寫少的併發場景。Java的list在遍歷時,若中途有別的線程對list容器進行修改,則會拋出ConcurrentModificationException異常。而CopyOnWriteArrayList因爲其"讀寫分離"的思想,遍歷和修改操做分別做用在不一樣的list容器,因此在使用迭代器進行遍歷時候,也就不會拋出ConcurrentModificationException異常了。框架

  •  CopyOnWriteArrayList缺點分析

        缺點也很明顯,一是內存佔用問題,畢竟每次執行寫操做都要將原容器拷貝一份,數據量大時,對內存壓力較大,可能會引發頻繁GC;二是沒法保證明時性,Vector對於讀寫操做均加鎖同步,能夠保證讀和寫的強一致性。而CopyOnWriteArrayList因爲其實現策略的緣由,寫和讀分別做用在新老不一樣容器上,在寫操做執行過程當中,讀不會阻塞但讀取到的倒是老容器的數據。源碼分析

  • 源碼分析 

          

         添加的邏輯很簡單,先將原容器copy一份,而後在新副本上執行寫操做,以後再切換引用。固然此過程是要加鎖的。性能

        刪除操做spa

        

        刪除操做同理,將刪除要刪除元素以外的其餘元素拷貝到新副本中,而後切換引用,將原容器引用指向新副本。同屬寫操做,須要加鎖。線程

        再來看看讀操做,CopyOnWriteArrayList的讀操做是不用加鎖的,性能很高。blog

        

        直接讀取便可,無需加鎖內存

        

相關文章
相關標籤/搜索