Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a synchronized block prevent other thread access to object?

If I do something to a list inside a synchronized block, does it prevent other threads from accessing that list elsewhere?

List<String> myList = new ArrayList<String>();

synchronized {
  mylist.add("Hello");
}

Does this prevent other threads from iterating over myList and removing/adding values?

I'm looking to add/remove values from a list, but at the same time protect it from other threads/methods from iterating over it (as the values in the list might be invalidated)

like image 709
Jimmy Avatar asked Nov 08 '10 10:11

Jimmy


2 Answers

No, it does not.

The synchronized block only prevents other threads from entering the block (more accurately, it prevents other threads from entering all blocks synchronized on the same object instance - in this case blocks synchronized on this).

You need to use the instance you want to protect in the synchronized block:

synchronized(myList) {
  mylist.add("Hello");
}

The whole area is quite well explained in the Java tutorial:

http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

like image 166
sleske Avatar answered Sep 19 '22 23:09

sleske


Yes, but only if all other accesses to myList are protected by synchronized blocks on the same object. The code sample you posted is missing an object on which you synchronize (i.e., the object whose mutex lock you acquire). If you synchronize on different objects or fail to synchronize at all in one instance, then other threads may very well access the list concurrently. Therefore, you must ensure that all threads have to enter a synchronized block on the same object (e.g., using synchronized (myList) { ... } consistently) before accessing the list. In fact, there is already a factory method that will wrap each method of your list with synchronized methods for you: Collections.synchronizedList.

However, you can certainly use Collections.synchronizedList to wrap your list so that all of its methods are individually synchronized, but that doesn't necessarily mean that your application's invariants are maintained. Individually marking each method of the list as synchronized will ensure that the list's internal state remains consistent, but your application may wish for more, in which case you will need to write some more complex synchronization logic or see if you can take advantage of the Concurrency API (highly recommended).

like image 24
ide Avatar answered Sep 21 '22 23:09

ide