Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to iterate over synchronized wrappers?

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?

like image 544
St.Antario Avatar asked Jan 04 '16 07:01

St.Antario


People also ask

What is a drawback of synchronized wrappers?

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.

Is synchronized method thread-safe?

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.

Is synchronized block more efficient than method?

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.

Why we use synchronized on the block when we can use it on the 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.


1 Answers

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.

like image 169
Sotirios Delimanolis Avatar answered Nov 15 '22 07:11

Sotirios Delimanolis