同步容器的定義
同步容器實現線程安全的方式是:將容器的狀態封裝起來,並對每一個公有方法都進行同步(加鎖),所以,每一次能夠訪問容器狀態的線程只有一個。這樣的結果就是容器的使用只能串行化。
同步容器有哪些
Vector,HashTable,同步的封裝容器
同步的封裝容器包括:Collection下的synchronized容器:
Collection.synchronizedList
Collection.synchronizedCollection
Collection.synchronizedMap
Collection.synchronizedSet
Collection.synchronizedSortedMap
Collection.synchronizedSortedSet
如何實現同步
這些同步容器實現同步的方式是:將它們的狀態封裝起來,並對每個公有方法進行同步,公有方法的同步鎖就是容器對象本身,所以,同步容器不允許併發。
同步容器通過其自身的鎖來保護它的方法
同步容器的問題
(1)併發問題:
雖然同步容器的每一個方法都是線程安全的,但是,多個方法的複合操作就有問題了。比如:迭代、跳轉和條件運算(先檢查,後執行)等複合操作就不能保證原子性。針對這個問題,遵循同步容器的規則,就是需要對複合操作進行額外的加鎖。這樣的結果就是該操作上的鎖太多,就會導致持有鎖的時間太長,和在該操作上的鎖競爭太激烈 。鎖的競爭越激烈,那麼,在該鎖上花的時間就越長。
(2)伸縮性問題:
對複合操作加鎖,則會使程序效率很低
(3)併發問題的表現就是(迭代器與ConcurrentModificationException)
同步容器的併發問題最容易出現在迭代器上,容器在迭代過程中,如果被修改,那麼就會拋出ConcurrentModificationException,(併發修改異常)。因爲容器的標準遍歷方式是iterater;iterater的設計採用的是:及時失敗(fail-fast),這意味着,當iterater發現容器在遍歷過程中被修改,就會拋出異常ConcurrentModificationException。
fail-fast的實現方式:有一個Counter,當容器被修改的時候,Counter會變化,在迭代過程中,如果檢測到Counter變化,則拋出ConcurrentModificationException。
注意:這種檢測不是隻有在併發的時候纔會出現異常。比如,當對象直接刪除元素而不是通過iterater.remove刪除時,也會拋出異常。