2015-02-06 52 views
1

如果我创建这样的列表:为什么要同步一个同步列表?

List<MyObj> myobjs = Collections.synchronizedList(new ArrayList<MyObj>()); 

相关的文档声称,此返回的列表的需要,以遍历元件进行同步。但是,我可以同步一个常规列表并使用同步块保护它。那么,为什么我需要一个“synchronizedList”?

返回由指定的 列表支持的同步(线程安全)列表。为了保证串行访问,通过返回列表完成对后备列表访问的所有访问是至关重要的。

当务之急是用户迭代它时,返回 名单上手动同步:

List list = Collections.synchronizedList(new ArrayList()); 
     ... 
    synchronized (list) { 
     Iterator i = list.iterator(); // Must be in synchronized block 
     while (i.hasNext()) 
      foo(i.next()); 
    } 

不遵循此建议将导致无法确定的 行为。如果指定的列表 是可序列化的,则返回的列表将是可序列化的。

参数:列表列表将被“包装”在同步列表中。 返回:指定列表的同步视图。

+1

它已经在这里回答:http://stackoverflow.com/questions/9468187/collections-synchronizedlist-and-synchronized。简单的操作保证是线程安全的,但迭代不是一个简单的操作。 – 2015-02-06 20:02:25

+0

我同意这些问题是相似的,但不完全重复。即我询问同步列表的用途是什么,如果你还需要同步,并且romsky询问在使用SynchronizedList时同步的目的是什么。 – paiego 2015-02-06 20:14:52

+0

因为它只能进行简单操作的同步......你会怎么做? – 2015-02-06 20:18:49

回答

3

synchronizedList是一种便捷的包装,可以避免在大多数情况下手动同步,但在迭代时不能进行手动同步。

在正常的非同步列表中,如果多线程使用它,则需要始终手动进行同步,因此使用synchronizedList可能会很方便。

需要synchronizedList的情况下,如果您将列表传递给某些未在列表中同步的第三方代码,但仍需要同步。但是,这很容易出错,因为您依赖于第三方代码不会遍历列表或使用其他非原子操作的事实,因此如果可能的话,最好完全避免这种情况(例如,通过复制列表)。

+1

谢谢......来自romski的文章,“同样重要的是要注意,任何使用迭代器(例如Collections.sort())的方法也需要封装在同步块中。” – paiego 2015-02-06 20:15:50