【 tulaoshi.com - 编程语言 】
                             
                            包装器实现 
        包装器实现是一种将它们的实际工作委托给一个特定 对象集 的实现,它在该 对象集 所提供的功能之上又增加了额外的功能。 对design patterns(设计样式)  爱好者来说,这是一个 decorator(油漆工) 样式。虽然有点异国情调,但确实简单明了。  
![]()
![]()
![]()
![]()
!-- frame contents --   !-- /frame contents --
![]()
![]()
![]()
![]() 
              这些实现是匿名的:不是提供一个公共类,JDK 提供一个 static factory method(静态方法)。 所有这些都可以在仅包含静态方法的Collections  API 中找到。         
同步包装器(Synchronization Wrappers)
        同步包装器将自动同步(线程安全的)添加到一个任意的 对象集。6个 核心 对象集 接口中的每一个都对应一个静态方法:    
   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);   
     每一个这样的方法都返回一个由特定 对象集 作为后备的同步(线程安全的)Collection。 为保证串行存取,所有对后备 对象集 的存取都必须通过返回的  对象集 来完成,这一点是至关重要的。 保证这一点的一个简便办法是不要保持对后备 对象集 的引用, 创建这样的同步 对象集 是一个小技巧:    
   List list = Collections.synchronizedList(new ArrayList());    
     一个用这种方式创建的对象集,每一比特都是线程安全的,就象VectorM那样的"正常"同步 对象集 一样。 在需要并发存取情况下,在返回的  对象集 上迭代时,用户对返回的 对象集 做手工同步是十分必要的。 这是因为迭代是通过对对象集 的多重调用完成的,它必须被编写为一个单独的最小单元操作(atomic  operation)。在一个包装器同步的 对象集 上的迭代惯用程序如下所示:    
   Collection c = Collections.synchronizedCollection(myCollection);   
   synchronized(c) {   
   Iterator i = c.iterator(); // Must be in the synchronized block!   
   while (i.hasNext())    
   foo(i.next());   
   }  
     在一个同步 Map 的 Collection视图上的迭代惯用程序与上述程序相似,但有一个诀窍,那就是,当在同步 Map 的Collection视图上迭代时,  用户必须对同步 Map 做手工同步,而不是对 Collection视图本身做同步:        
![]()
![]()
![]()
![]()
!-- frame contents --   !-- /frame contents --
![]()
![]()
![]()
![]()
   Map m = Collections.synchronizedMap(new HashMap());
   ...   
   Set s = m.keySet(); // Needn"t be in synchronized block
   ...   
   synchronized(m) { // Synchronizing on m, not s!   
   Iterator i = s.iterator(); // Must be in synchronized block   
   while (i.hasNext())   
   foo(i.next());
   }   
     包装器实现的一个小的缺陷是你不能执行一个包装器实现的非接口操作。因此,比如在上面的 List 的例子中,你就不能调用包装的ArrayList上的ensureCapacity