Synchronization Control of Collections Collections. Synchronized Collection Sets

Keywords: Java JDK

Synchronization Control of Collections Collections. Synchronized Collection Sets

Several synchronized Xxx methods are provided in the Collections class:
This method returns the synchronization object corresponding to the specified collection object to solve the thread security problem when multithreading accesses the collection concurrently.

The most commonly used collection classes are List, Set, Map and so on, while the three implementation classes commonly used in the collection framework: HashSet, ArrayList and HashMap are thread insecure. Collections provides several static methods for creating synchronous collections:

Collection c = Collections.synchronizedCollection(new ArrayList());
List list = Collections.synchronizedList(new ArrayList());
Set set = Collections.synchronizedSet(new HashSet());
Map map = Collections.synchronizedMap(new HashMap());

static class SynchronizedCollection<E> implements Collection<E>, Serializable {  
    // use serialVersionUID from JDK 1.2.2 for interoperability  
    private static final long serialVersionUID = 3053995032091335093L;  
    final Collection<E> c;  // Backing Collection  
    final Object mutex;     // Object on which to synchronize  

    SynchronizedCollection(Collection<E> c) {  
        if (c==null)  throw new NullPointerException();  
        this.c = c;  
        mutex = this;  
    }  
    SynchronizedCollection(Collection<E> c, Object mutex) {  
        this.c = c;  
        this.mutex = mutex;  

    }  
    ...
}  

The declaration of the java. util. Collections. synchronized Collection () method.
public static Collection synchronizedCollection(Collection c)
Function: Method is used to obtain support for specified sets of synchronized (thread-safe) collections
Parametric c: A "wrapped" set in a synchronous set
Return value
Returns a synchronous view of the specified collection in a method call.

static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>  
implements RandomAccess {  
    static final long serialVersionUID = 1530674583602358482L; 
    SynchronizedRandomAccessList(List<E> list) {  
        super(list);  
    }  
    SynchronizedRandomAccessList(List<E> list, Object mutex) {  
        super(list, mutex);  
    }  

    public List<E> subList(int fromIndex, int toIndex) {  
        synchronized(mutex) {  
            return new SynchronizedRandomAccessList<E>(list.subList(fromIndex, toIndex), mutex);  
        }  
    }  
    private Object writeReplace() {  
        return new SynchronizedList<E>(list);  
    }  
}  

Statement of the java.util.Collections.synchronizedList() method:

public static <T> List<T> synchronizedList(List<T> list) {  
return (list instanceof RandomAccess ?  
               new SynchronizedRandomAccessList<T>(list) :  
               new SynchronizedList<T>(list));//Finally, different packing classes are implemented according to different list types.  
} 

Functions:
Returns a list of synchronized (thread-safe) lists for thread-safe List objects that, when accessed by threads, need to acquire a lock on the object (regardless of whether it is in a synchronized synchronized block).
Parameter list:
List to be converted to thread-safe
When one thread acquires the lock of the object, other threads, whether or not using syn synchronization block, wait for the thread that acquires the lock to execute after it has finished executing, when calling add, remove, etc.

Synchronized List adds synchronized keywords to some operations to ensure thread safety. But its iterator() operation is not thread-safe (Synchronized List is suitable for multi-threaded environments where Iterator is not required). Part of the Synchronized List code is as follows:

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 ListIterator<E> listIterator() {  
    return list.listIterator(); // Must be manually synched by user, otherwise Concurrent ModificationException may still be thrown  
}  
public ListIterator<E> listIterator(int index) {  
    return list.listIterator(index); // Must be manually synched by user, otherwise Concurrent ModificationException may still be thrown
}

// The SynchronizedMap class is a static internal class defined in Collections. It implements the Map interface, and implements each of these methods. It controls synchronized keywords synchronously.

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {  
    return new SynchronizedMap<K,V>(m);  
} 

Mutex is the current Synchronized Collection object, and Synchronized Random Access List inherits from Synchronized List, Synchronized List inherits from Synchronized Collection, so the mutex in Synchronized Random Access List is also the this object of Synchronized Random Access List.

1,Collections.synchronizedCollection()
// create vector object 
Vector<String> vector = new Vector<String>();
vector.add("1");

// create a synchronized view
Collection<String> c = Collections.synchronizedCollection(vector); 
System.out.println("Synchronized view is :"+c);

2,Collections.synchronizedList()
List = Collections. synchronized List (new ArrayList ()); //ArrayList is non-linear security, and iterators returned by such iterator and listIterator methods are fast failures

synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
          System.out.println("list: "+i.next());
} 

// create List object
List = new ArrayList (); // After creating an iterator, unless the list is structurally modified by the iterator's own remove or add method, the iterator will throw Concurrent ModificationException whenever and in any way it modifies the list.

list.add("1"); // add first item
// create a synchronized list
List<String> synlist = Collections.synchronizedList(list); //synlist is a thread-safe List < String > object
new Thread(){  
    public void run() {  
        synchronized (synlist) {  
            try {  
                Thread.sleep(100);  
            } 
            catch (InterruptedException e) {  
            };  
            synlist.add("2");  
            System.out.println("Operation1 synlist: "+synlist.size() + ", synlist item2: "+synlist.get(2));  
        }  
    };  
}.start();   

new Thread(){  
    public void run() {  
        synlist.add("3");  
        System.out.println("Operation2 synlist: "+synlist.size()+", synlist item2: "+synlist.get(2));  
    };  
}.start(); 

3,Collections.synchronizedMap()

Map<String,String> map = Collections.synchronizedMap(new TreeMap<String,String>());
map.put("key1","value1");
map.put("key2","value2");
Set<Entry<String,String>> entries = map.entrySet();
Iterator<Entry<String,String>> iter = entries.iterator();

synchronized (map) {
    while(iter.hasNext()){
        System.out.println(iter.next()); 
        //The Concurrent ModificationException exception may be thrown when iterating over elements, so synchronized synchronization mechanism can be added.
        map.remove("key2");  
    }
}

Posted by dvayne on Thu, 20 Jun 2019 12:46:17 -0700