What is a synchronous container?

Synchronized makes the container thread-safe by modifying the container with the synchronized keyword to ensure that only one thread is using the container at a time. Synchronized means synchronization, and is embodied in changing multiple threads into serial waiting to be executed. (Note, however, that compound operations are not thread-safe. For example, thread A obtains the tail node in the first step and increments the value of the tail node in the second step. However, thread B deletes the tail node when thread A completes the first step and returns A null pointer when thread A completes the second step.

What is a concurrent container?

A concurrent container is one that allows multiple threads to use the container simultaneously and is thread-safe. In order to improve concurrency as much as possible, Java concurrency toolkit uses a variety of optimization methods to improve the execution efficiency of concurrent containers, the core is: lock, CAS (no lock), COW (read and write separation), subsection lock.

Synchronization of the container

1.Vector

Vector implements the List interface just as ArrayList does, and operates on arrays just as ArrayList does, except that Vertor modifiers all methods that might be thread unsafe with synchronized.

2.Stack

Stack is a subclass of Vertor, and Stack implements a first-in-last-out Stack. Synchronized modification is carried out in the operations such as out and on the stack.

3.HashTable

HashTable implements the Map interface. It implements basically the same functionality as HashMap (HashTable cannot store NULL, whereas HashMap keys and values can store NULL). The difference is that HashTable uses synchronized to modify methods.

4. The synchronous collection class provided by Collections

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

In all three containers, Collections added synchronized synchronization to their original operations through the proxy mode. However, the granularity of synchronized is too large, resulting in low efficiency in multi-threaded processing. Therefore, in JDK1.5, concurrent containers under packages were introduced to deal with the problem of low efficiency of container processing under multi-threading.

Concurrent container

1.CopyOnWriteArrayList

CopyOnWriteArrayList is equivalent to implementing a thread-safe ArrayList. The mechanism of CopyOnWriteArrayList is to copy a copy of the array when writing to the container, and then assign a reference to the copy array to the container. At the bottom is synchronization through ReentrantLock. However, it sacrifices the consistency of the container for the high concurrency efficiency of the container (old data is read during copy). Therefore, it cannot be used in scenarios where strong consistency is required.

2.CopyOnWriteArraySet

CopyOnWriteArraySet, like CopyOnWriteArrayList, is a Set that implements CopyOnWrite.

3.ConcurrentHashMap

ConcurrentHashMap is equivalent to implementing thread-safe HashMap. The key is unordered, and neither key nor value can be null. Prior to JDK8, ConcurrentHashMap used segwise locking to improve concurrency, requiring locks only when operating on key-value pairs of the same segment. In JDK8, the lock segmentation mechanism is abandoned and CAS algorithm is used instead.

4.ConcurrentSkipListMap

ConcurrentSkipListMap is the equivalent of implementing thread-safe TreeMap. Keys are ordered, and neither key nor value can be null. It uses skip list mechanism to replace red black tree. Why not stick with red-black trees? Because red-black trees need to be rotated when nodes are inserted or deleted, the granularity to be controlled is large. While skip lists use linked lists, using lock-free CAS mechanism to achieve high concurrent thread safety.

5.ConcurrentSkipListSet

ConcurrentSkipListSet, like ConcurrentSkipListMap, is a high-concurrency thread-safe TreeSet.

The Queue type

blocking

1.ArrayBlockingQueue

ArrayBlockingQueue is a bounded blocking thread-safe queue implemented using arrays. Further filling of elements into a full queue will cause the current thread to block. Fetching elements from an empty queue causes the current thread to block. ReentrantLock is used to ensure thread safety in concurrent situations.

2.LinkedBlockingQueue

LinkedBlockingQueue is an arbitrary (actually bounded) FIFO blocking queue based on a one-way list. Access and remove operations are performed at the head of the queue, and add operations are performed at the tail of the queue, protected by separate locks. Only operations that may involve multiple nodes are locked at the same time.

3.PriorityBlockingQueue

PriorityBlockingQueue is an unbounded blocking queue that supports a priority. By default, elements are arranged in natural ascending order. You can also customize your class to implement the compareTo() method to specify element collation,

4.DelayQueue

DelayQueue is an unbounded blocking queue implemented internally using priority queues. How long must the element node data wait before it can be accessed? Wait when the data fetch queue is empty, and wait timeout when there is data but the delay time is not reached.

5.SynchronousQueue

SynchronousQueue has no capacity and is a blocking queue that does not store elements. It simply passes the elements to the consumer and must wait until the added elements in the queue are consumed before adding new elements. It’s equivalent to a conveyor belt of capacity one.

6.LinkedTransferQueue

LinkedTransferQueue is an unbounded transport blocking queue with linked lists. It combines the advantages of ConcurrentLinkedQueue, SynchronousQueue, and LinkedBlockingQueue. The specific mechanism is complicated.

7.LinkedBlockingDeque

LinkedBlockingDeque is a two-way blocking queue consisting of a linked list structure. A two-way queue is one in which elements can be inserted and removed from both ends of the queue.

Non-blocking type

1.ConcurrentLinkedQueue

ConcurrentLinkedQueue is a thread-safe, unbounded, non-blocking queue whose underlying data structure is implemented using a one-way linked list. Queue entry and queue exit operations are thread-safe using the oft-mentioned CAS.

The author’s level is limited, if there are mistakes, please comment.

My personal blog, vc2x.com