container
1. Synchronized container
1. Concept
Synchronized containers are all thread-safe, but in some scenarios, locks may be required to protect compound operations.
Composite class operations such as:
iteration (repeatedly visit elements, traverse all elements in the container),
jump (find the next element of the current element according to the specified damage), and conditional operations.
These composite operations may show unexpected behavior when multiple threads concurrently modify the container. The
most classic is ConcurrentModificationException. The reason is that when the container is iterated,
the content is concurrently modified. This is due to the early iterators involved. The issue of concurrent modification is not considered.
2. Example
Synchronization class container: such as the ancient Vector / HashTable
, the synchronization functions of these containers are created and implemented by factory methods such as Collections.synchronized of JDK.
The underlying mechanism is nothing more than to use the traditional synchronized keyword to synchronize each public method,
so that only one thread can access the state of the container at a time. This obviously does not meet our high concurrency requirements in the Internet era. While ensuring thread safety, it must also have good enough performance.
package com.study.current.thread.day02; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Vector; public class VectorDemo { public static Vector<String> vector = new Vector<String>(); /** * @param args */ public static void main(String[] args) { /** * Convert non-thread-safe to thread-safe */ // Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>()); for(int i = 0 ; i< 100 ; i++){ vector.add(i+""); } /** * The operation reports the following exception * Although Vector is thread-safe, an error will still be reported during compound operations * Exception in thread "main" java.util.ConcurrentModificationException */ // for(Iterator<String> iterator = vector.iterator(); iterator.hasNext();){ // System.out.println(iterator.next()); // vector.remove(0); // } /** * Separate operation, thread-safe */ for(int i = 0 ; i < 10 ; i++){ new Thread(new Runnable() { public void run() { while(true){ if(vector.isEmpty()){ break ; } System.out.println(Thread.currentThread().getName()+"----"+vector.remove(0)); } } },i+"").start(); } } }
2. Concurrent Containers
After jdk5.0, a variety of concurrent containers are provided to replace synchronous containers to improve performance. The state of the synchronization class container is serialized. Although they achieve thread safety,
they severely reduce concurrency and, in a multithreaded environment, severely reduce application throughput.
The concurrency container is specially designed for concurrency, using ConcurrentHashMap to replace the traditional HashTable for hashing, and
adding support for some common compound operations in ConcurrentHashMap. And the use of CopyOnWriteArrayList instead of Vector
concurrent CopyOnWriteArraySet, concurrent Queue,
ConcurrentLinkedQueue and LinkedBlockingQueue, the former is a high-performance queue, the latter is a blocking form of queue
3. ConcurrentMap
ConcurrentMap
ConcurrentSkipListMap (support concurrent sorting function)
ConcurrentHashMap internal use segment ( segment) to represent these different parts, each segment is actually a small HashTable, and
they have their own locks. As long as multiple modification operations occur on different segments, they can proceed concurrently. Divide a whole into 16 segments.
That is, concurrent modification operations that support up to 16 threads. This is also a solution to reduce lock granularity and reduce lock contention when living in a multi-threaded scenario.
And most of the shared variables in the code are declared using the volatile keyword. The purpose is to get the modified content at the first time, and the performance is very good.
4. Copy-On-Write Container
Application scenario: Read more and write less
Copy-On-Write container
Copy-On-Write, referred to as COW, is an optimization strategy used in program design.
There are two types of COW containers in JDK: CopyOnWriteArrayList and CopyOnWriteArraySet
concepts:
Copy-On-Write containers are copy-on-write containers. The popular understanding is that when we add elements to a container, we do not directly add to the current container,
but first copy the current container and copy a new container. The advantage of this is that we can read the Copy-On-Write container concurrently
without locking, because the current container will not add any elements. Therefore, the Copy-On-Write container is also a kind of idea of separation of reading and writing, and different containers are read and written.