1. 程式人生 > >JAVA並發容器之CopyOnWrite容器

JAVA並發容器之CopyOnWrite容器

最終一致性 使用 當我 .com 比較 響應時間 get 理解 資源

學習資源:http://www.cnblogs.com/dolphin0520/p/3938914.html

  CopyOnWrite容器即寫時復制的容器。通俗的理解是當我們往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行Copy,復制出一個新的容器,然後新的容器裏添加元素,添加完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行並發的讀,而不需要加鎖,因為當前容器不會添加任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器。

CopyOnWrite並發容器用於讀多寫少的並發場景。讀的時候不需要加鎖

使用CopyOnWriteMap需要註意兩件事情:

  1. 減少擴容開銷。根據實際需要,初始化CopyOnWriteMap的大小,避免寫時CopyOnWriteMap擴容的開銷。

  2. 使用批量添加。因為每次添加,容器每次都會進行復制,所以減少添加次數,可以減少容器的復制次數。

CopyOnWrite的缺點

內存占用問題。因為CopyOnWrite的寫時復制機制,所以在進行寫操作的時候,內存裏會同時駐紮兩個對象的內存,舊的對象和新寫入的對象(註意:在復制的時候只是復制容器裏的引用,只是在寫的時候會創建新對象添加到新容器裏,而舊容器的對象還在使用,所以有兩份對象內存)。如果這些對象占用的內存比較大,比如說200M左右,那麽再寫入100M數據進去,內存就會占用300M,那麽這個時候很有可能造成頻繁的Yong GC和Full GC。之前我們系統中使用了一個服務由於每晚使用CopyOnWrite機制更新大對象,造成了每晚15秒的Full GC,應用響應時間也隨之變長。

  針對內存占用問題,可以通過壓縮容器中的元素的方法來減少大對象的內存消耗,比如,如果元素全是10進制的數字,可以考慮把它壓縮成36進制或64進制。或者不使用CopyOnWrite容器,而使用其他的並發容器,如ConcurrentHashMap。

數據一致性問題。CopyOnWrite容器只能保證數據的最終一致性,不能保證數據的實時一致性。所以如果你希望寫入的的數據,馬上能讀到,請不要使用CopyOnWrite容器。

JAVA並發容器之CopyOnWrite容器