首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Collections API:包裝器實現與同步包裝器詳解

     編輯:Java 程式設計入門

包裝器實現模式

包裝器實現是一種將核心工作委託給特定集合對象,並在其功能基礎上增加額外行為的設計模式。對設計模式愛好者而言,這正是 Decorator(裝飾器)模式 的經典應用。雖然概念聽起來略顯「異國情調」,但實際運作極為直觀簡單。

這些實現類均為匿名類:JDK 不提供公共類,而是透過 Collections 工具類中的靜態工廠方法來獲取實例。所有相關方法均定義在 java.util.Collections 中。

同步包裝器

同步包裝器能為任意集合自動添加線程安全特性。針對六大核心集合接口,Collections 提供了對應的靜態方法:

public static Collection synchronizedCollection(Collection c);
public static Set synchronizedSet(Set s);
public static List synchronizedList(List list);
public static Map synchronizedMap(Map m);
public static SortedSet synchronizedSortedSet(SortedSet s);
public static SortedMap synchronizedSortedMap(SortedMap m);

每個方法均返回一個由指定集合作為後備存儲的同步(線程安全)集合。關鍵點:為確保串行訪問,所有對後備集合的操作必須透過返回的同步集合完成。最簡單的做法是不保留對原始集合的引用,例如:

List list = Collections.synchronizedList(new ArrayList());

這樣創建的集合在單操作層面上是線程安全的,類似於早期的 Vector。然而,在並發環境下對返回集合進行迭代時,必須手動同步,因為迭代涉及多次方法調用,需作為單一原子操作執行。

同步集合迭代慣用寫法

Collection c = Collections.synchronizedCollection(myCollection);
synchronized(c) {
    Iterator i = c.iterator(); // 必須在同步塊內
    while (i.hasNext())
        foo(i.next());
}

同步 Map 的集合視圖迭代注意事項

迭代同步 Map 的集合視圖(如 keySet()、values()、entrySet())時,必須鎖定 Map 本身,而非視圖對象:

Map m = Collections.synchronizedMap(new HashMap());
Set s = m.keySet(); // 無需同步塊
synchronized(m) { // 鎖定 m,而非 s
    Iterator i = s.iterator(); // 必須在同步塊內
    while (i.hasNext())
        foo(i.next());
}

包裝器實現的局限

包裝器實現的一個小缺陷是無法調用被包裝對象特有的非接口方法。例如上例中,無法在同步 List 上調用 ArrayList 特有的 ensureCapacity() 方法。




  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved