I decided to dig into source code a bit and noticed that Collections.synchronizedList(List)
is implemented as follows:
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<T>(list) :
new SynchronizedList<T>(list));
}
where the SynchronizedList
nested class is:
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
public boolean More ...equals(Object o) {
synchronized(mutex) {return list.equals(o);}
}
//ommited
public void add(int index, E element) {
synchronized(mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized(mutex) {return list.remove(index);}
}
//rest is ommited
}
As can bee seen, the class useses a private
lock object to provide thread-safety. But the documentation allows us to iterate over it using locking on the objetct returned by the factory method.
It is imperative that the user manually synchronize on the returned list when iterating over it:
So, we use different locks for iterating and modifying list (add
, remove
, etc).
Why is it considered to be safe?
Although synchronized wrappers can be safely used in multi-threaded applications, they have drawbacks as explained in the next section. 4. Concurrent Collections. A drawback of synchronized collections is that their synchronization mechanism uses the collection object itself as the lock object.
Thread safe means: method becomes safe to be accessed by multiple threads without any problem at the same time. synchronized keyword is one of the way to achieve 'thread safe'. But Remember:Actually while multiple threads tries to access synchronized method they follow the order so becomes safe to access.
A Java synchronized block doesn't allow more than one JVM, to provide access control to a shared resource. The system performance may degrade because of the slower working of synchronized keyword. Java synchronized block is more efficient than Java synchronized method.
A Synchronized block is a piece of code that can be used to perform synchronization on any specific resource of the method. A Synchronized block is used to lock an object for any shared resource and the scope of a synchronized block is smaller than the synchronized method.
The Collections#synchronizedList
method
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
uses that single parameter constructor that you've shown in your question. That constructor invokes the super constructor which sets this
as the mutex
. All the methods are synchronized
on mutex
, this
.
The documentation is telling you to also synchronize on the instance while iterating. That reference is the same as the this
within the method bodies.
All these actions are (should, if you do it right) therefore sharing the same lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With