Java集合(16)--快速失敗機制(Fail-Fast)

來源:互聯網
上載者:User

標籤:

     迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步並發修改做出任何硬性保證。快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException,為提高這類迭代器的正確性而編寫一個依賴於此異常的程式是錯誤的做法:迭代器的快速失敗行為應該僅用於檢測 bug。

     它是Java集合的一種錯誤檢測機制。當多個線程對集合進行結構上的改變的操作時,有可能會產生fail-fast機制。記住是有可能,而不是一定。

     ConcurrentModificationException不會始終指出對象已經由不同線程並發修改,如果單線程違反了規則,同樣也有可能會拋出該異常。

     迭代器在調用next()、remove()方法時都是調用checkForComodification()方法,該方法主要就是檢測modCount == expectedModCount ? 若不等則拋出ConcurrentModificationException 異常,從而產生fail-fast機制。

 

 

fail-fast解決方案:(對於ArrayList)

 

方案一:在遍曆過程中所有涉及到改變modCount值得地方全部加上synchronized或者直接使用Collections.synchronizedList,這樣就可以解決。但是不推薦,因為增刪造成的同步鎖可能會阻塞遍曆操作。

 

方案二:使用CopyOnWriteArrayList來替換ArrayList。

CopyOnWriteArrayList所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的。

該類產生的開銷比較大,但是在兩種情況下,它非常適合使用。1:在不能或不想進行同步遍曆,但又需要從並發線程中排除衝突時。2:當遍曆操作的數量大大超過可變操作的數量時。

 

CopyOnWriterArrayList根本就不會產生ConcurrentModificationException異常,也就是它使用迭代器完全不會產生fail-fast機制。

 

 

public boolean add(E paramE) {          ReentrantLock  localReentrantLock = this.lock;          localReentrantLock.lock();          try {              Object[] arrayOfObject1 = getArray();              int i = arrayOfObject1.length;              Object[] arrayOfObject2 = Arrays.copyOf(arrayOfObject1, i + 1);              arrayOfObject2[i] = paramE;              setArray(arrayOfObject2);              int j = 1;              return j;          } finally {              localReentrantLock.unlock();          }      }              final void setArray(Object[] paramArrayOfObject) {          this.array = paramArrayOfObject;      }  

 

 

      以上紅色的三句代碼使得CopyOnWriterArrayList不會拋ConcurrentModificationException異常。他們所展現的魅力就在於copy原來的array,再在copy數組上進行add操作,這樣做就完全不會影響COWIterator中的array了。

 

      任何對array在結構上有所改變的操作(add、remove、clear等),CopyOnWriterArrayList都會copy現有的資料,再在copy的資料上修改,這樣就不會影響COWIterator中的資料了,修改完成之後改變原有資料的引用即可。同時這樣造成的代價就是產生大量的對象,同時數組的copy也是相當有損耗的.

 

Java集合(16)--快速失敗機制(Fail-Fast)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.