What is the difference in behavior between these two usages of synchronized on a list

旧巷老猫 提交于 2019-12-05 07:03:37

If you don't lock around the iteration, you will get a ConcurrentModificationException if another thread modifies it during the loop.

Synchronizing all of the methods doesn't prevent that in the slightest.

This (and many other things) is why Collections.synchronized* is completely useless.
You should use the classes in java.util.concurrent. (and you should think carefully about how you will guarantee you will be safe)

As a general rule of thumb:

Slapping locks around every method is not enough to make something thread-safe.

For much more information, see my blog

synchronizedList only makes each call atomic. In your case, the loop make multiple calls so between each call/iteration another thread can modify the list. If you use one of the concurrent collections, you don't have this problem.

To see how this collection differs from ArrayList.

List<String> list = new CopyOnWriteArrayList<String>();
list.addAll(Arrays.asList("a,b,c,d,e,f,g,h,z".split(",")));

for(String s: list) {
    System.out.print(s+" ");
    // would trigger a ConcurrentModifcationException with ArrayList
    list.clear(); 
}

Even though the list is cleared repeatedly, it prints the following because that wa the contents when the iterator was created.

a b c d e f g h z 

The second code needs to be synchronized because of the way synchronized lists are implemented. This is explained in the javadoc:

It is imperative that the user manually synchronize on the returned list when iterating over it

The main difference between the two code snippets is the effect of the add operations:

  • with the synchronized list, you have a visibility guarantee: other threads will see the newly added items if they call synchronizedList.get(..) for example.
  • with the ArrayList, other threads might not see the newly added items immediately - they might actually not ever see them.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!