列表中这两个同步用法之间的行为有何不同?

Viv*_*ath 6 java concurrency synchronized

List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");

synchronized(list) {
    Iterator<String> i = list.iterator();
    while(i.hasNext()) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");

List<String> synchronizedList = Collections.synchronizedList(list);

synchronized(synchronizedList) {
    Iterator<String> i = synchronizedList.iterator();
    while(i.hasNext()) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我不清楚synchronized当同步列表提供对列表的线程安全访问时,为什么在第二个实例中需要.

SLa*_*aks 6

如果你没有锁定迭代,如果另一个线程在循环期间修改它,你将得到一个ConcurrentModificationException.

同步所有方法并不能防止这种情况发生.

这(以及许多其他事情)是为什么Collections.synchronized*完全没用.
你应该使用这些类java.util.concurrent.(你应该仔细考虑如何保证你的安全)

一般的经验法则是:

对每个方法进行拍打锁定不足以使线程安全.

有关更多信息,请参阅我的博客

  • 除了synchronizedList()之外的+1并非完全没用,它通常不是一个完整的解决方案. (5认同)
  • @VivinPaliath:`synchronizedList`将确保调用单个方法不会通过相互竞争来破坏集合.它无法帮助您确保结构安全. (2认同)