1. 程式人生 > >java-快速失敗和安全失敗

java-快速失敗和安全失敗

1.Fail-fast是什麼?

快速失敗(fail-fast)

在用迭代器遍歷一個集合物件時,如果遍歷過程中對集合物件的內容進行了修改(增加、刪除、修改),則
會丟擲Concurrent Modification Exception。

2.Fail-fast的原理?

在這裡插入圖片描述

在呼叫 next() 和 remove()時,都會執行 checkForComodification()。
若 modCount 不等於 expectedModCount,
則丟擲ConcurrentModificationException異常,產生fail-fast事件。

在這裡插入圖片描述

無論是add()、remove(),還是clear(),只要涉及到修改集合中的元素個數時,都會改變modCount的值


在這裡插入圖片描述

ConcurrentModificationException異常,產生fail-fast事件。
**

怎麼解決:
1.使用iterator操作
2.將ArrayList替換成java.util.concurrent包下對應的類

3.用fail-safe改進?

安全失敗(fail-safe)

採用安全失敗機制的集合容器,在遍歷時不是直接在集合內容上訪問的,而是先複製原有集合內容,在拷貝的

集合上進行遍歷。
**

Fail-safe原理

**
在這裡插入圖片描述

併發容器:CopyOnWrite容器

CopyOnWrite容器即寫時複製的容器。


以新增為例:通俗的理解是當我容器新增元素的時候,不直接往當前容器新增,而是先將當前容器進行Copy,複製出一個新的容器,然後新的容器裡新增們往一個元素,新增完元素之後,再將原容器的引用指向新的容器。


以新增為例:這樣做的好處是我們可以對CopyOnWrite容器進行併發的讀,而不需要加鎖,因為當前容器不會新增任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器。

4.總結-比較fail-fast與fail-safe?

在這裡插入圖片描述

使用場景

> java.util包下的集合類都是快速失敗的,不能在多執行緒下發生併發修改(迭代過程中被修改),迭代器的快速失敗行為應該僅用於檢測程式錯誤。
> 
> java.util.concurrent包下的容器都是安全失敗,可以在多執行緒下併發使用,併發修改。
> 
> CopyOnWriteArrayList中寫操作需要大面積複製陣列,所以效能肯定很差,但是讀操作因為操作的物件和寫操作不是同一個物件,讀之間也不需要加鎖,讀和寫之間的同步處理只是在寫完後通過一個簡單的“=”將引用指向新的陣列物件上來,這個幾乎不需要時間,這樣讀操作就很快很安全,適合在多執行緒裡使用,絕對不會發生ConcurrentModificationException,所以最後得出結論:CopyOnWriteArrayList適合使用在讀操作遠遠大於寫操作的場景裡,比如快取。