Reputation: 169
For example, in the code below, we have to wrap list in a synchronized block when doing the iteration. Does the Collections.synchronizedList make the list synchronized? Why do we do this if it doesn't provide any convenience? Thanks!
List<Integer> list = Collections.synchronizedList( new ArrayList<>(Arrays.asList(4,3,52)));
synchronized(list) {
for(int data: list)
System.out.print(data+" ");
}
Upvotes: 0
Views: 295
Reputation: 30839
Collections.synchronizedList
method synchronises methods like add
, remove
. However, it does not synzhronize iterator()
method. Consider the following scenario:
In this case, you will get ConcurrentModificationException
and hence, it's imperative to synzhronize the calls to iterator()
method.
Upvotes: 0
Reputation: 140484
Why do we do this if it doesn't provide any convenience
That it does not help you when iterating is not the same as providing no convenience.
All of the methods - get
, size
, set
, isEmpty
etc - are synchronized. This means that they have visibility of all writes made in any thread.
Without the synchronization, there is no guarantee that updates made in one thread are visible to any other threads, so one thread might see a size of 5 which another sees a size of 6, for example.
The mechanism for making the list synchronized is to make all of its methods synchronized
: this effectively means that the body of the method is wrapped in a synchronized (this) { ... }
block.
This is still true of the iterator()
method: that too is synchronized
. But the synchronized
block finishes when iterator()
returns, not when you finish iterating. It's a fundamental limitation of the way the language is designed.
So you have to help the language by adding the synchronized block yourself.
Upvotes: 2
Reputation: 298
See https://docs.oracle.com/javase/tutorial/collections/implementations/wrapper.html
The reason is that iteration is accomplished via multiple calls into the collection, which must be composed into a single atomic operation.
Also see https://www.baeldung.com/java-synchronized-collections
Upvotes: 2
Reputation: 8758
Wrapper is used to synchronize addition and removal elements from wrapped collection.
JavaDoc mentions that iteration is not synchronized an you need to synchronize it yourself.
* It is imperative that the user manually synchronize on the returned
* list when iterating over it
But other access operations are thread-safe and also establish happens before relation (since they use synchronized
).
Upvotes: 0