NOTE

Collections.synchronizedList

1. What It Is: a thread-safe list. 2. Usage. 3. Source analysis: synchronizedList, SynchronizedList construction, mutex initialization, and synchronized method delegation.

JavaCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. What It Is

A thread-safe list.

2. How to Use It

public class SychronizedListTest
{
    public static void main(String[] args) throws InterruptedException
    {
        List<Integer> list = Collections.synchronizedList(new ArrayList<>());
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++)
            {
                list.add(i);
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 10000; i < 20000; i++)
            {
                list.add(i);
            }
        });

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        assert list.size() == 20000;

        for (int i = 0; i < 20000; i++)
        {
            assert list.contains(i);
        }

        list.remove(2);
        System.out.println(list.contains(1));// true
        System.out.println(list.contains(2));// false

    }
}

3. Source Analysis

3.1. synchronizedList Method

public static <T> List<T> synchronizedList(List<T> list) {
    return (list instanceof RandomAccess ?
            new SynchronizedRandomAccessList<>(list) :
            // Implemented with SynchronizedList
            new SynchronizedList<>(list));
}

3.1.1. Call the SynchronizedList Constructor

static class SynchronizedList<E>
        extends SynchronizedCollection<E>
        implements List<E> {

        // Stores the List
        final List<E> list;

        SynchronizedList(List<E> list) {
            // Calls the SynchronizedCollection constructor
            super(list);
            this.list = list;
        }


}

3.1.2. Initialize the Lock Object to the List Instance Being Constructed

static class SynchronizedCollection<E> implements Collection<E>, Serializable {

    // Modified by final, so the reference cannot change
    final Collection<E> c;  // Backing Collection
    final Object mutex;     // Object on which to synchronize

    SynchronizedCollection(Collection<E> c) {
        this.c = Objects.requireNonNull(c);
        // Use the instance currently being constructed as the lock
        mutex = this;
    }

3.2. Other Methods

public E get(int index) {
    synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
    synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
    synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
    synchronized (mutex) {return list.remove(index);}
}

3.2.1. Lock with a synchronized Block

synchronized (mutex)
{
//...
}

3.2.2. Then Call the List Method

list.remove(index)

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub