Java basics: thread-safe collection classes

1. Wrap thread-unsafe collections

The ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, etc. learned in the collection are all thread-unsafe. That is to say, when multiple concurrent threads store and retrieve elements from these collections, they may destroy these collections. Data integrity.

If multiple threads in the program may access these collections, you can use the class methods provided by Collections to package these collections into thread-safe collections. Collections provides the following static methods.

Insert picture description hereFor example, if you want to use thread-safe HashMap in multiple threads, you can use the following code:

 使用Collections的synchronizedMap方法将一个普通的
 HashMap map = (HashMap) Collections.synchronizedMap(new HashMap<>());

Note:
If you need to wrap a collection into a thread-safe collection, you should wrap it immediately after creation, as shown in the above program-when the HashMap object is created, it is immediately wrapped into a thread-safe HashMap object.

2. Thread-safe collection class

Starting from Java5, a large number of collection interfaces and implementation classes that support efficient concurrent access are provided under the java.util.concurrent package, as shown in the following figure:
Insert picture description hereAs can be seen from the class diagram shown in the figure above, these thread-safe collection classes are divided into There are two categories:

(1) Collection classes starting with Concurrent: such as ConcurrentHashMap, ConcurrentLinkedQueue, ConcurrentLinkedDeque, ConcurrentSkipListMap and ConcurrentSkipListSet.

(2) Collection classes starting with CopyOnWrite: such as CopyOnWriteArrayList, CopyOnWriteArraySet.

The collection classes starting with Concurrent represent collections that support concurrent access. They can support concurrent write access by multiple threads. All operations of these write threads are thread-safe, but read operations do not need to be locked. The collection class starting with Concurrent uses a more complex algorithm to ensure that the entire collection will never be locked, so it has better performance when writing concurrently.

When multiple threads share access to a common collection, ConcurrentLinkedQueue is an appropriate choice. ConcurrentLinkedQueue does not allow the use of null elements. ConcurrentLinkedQueue implements multi-threaded efficient access, and multiple threads do not need to wait when accessing the ConcurrentLinkedQueue collection.

By default, ConcurrentHashMap supports 16 threads to write concurrently. When more than 16 threads write data to the Map concurrently, some threads may need to wait. In fact, the program supports more concurrent writing threads by setting the concurrencyLevel construction parameter (default value is 16).

Unlike the HashMap and normal collections introduced earlier, because ConcurrentLinkedQueue and ConcurrentHashMap support multi-threaded concurrent access, when using an iterator to traverse elements, the iterator may not reflect the changes made after the iterator is created, but the program No exception will be thrown.

Java 8 expands the function of ConcurrentHashMap, and adds more than 30 new methods to this class. These methods can support the execution of focus operations with the help of Stream and Lambda expressions. The new methods of ConcurrentHashMap can be roughly divided into the following three categories:

Insert picture description hereIn addition, ConcurrentHashMap also adds mappingCount(), newKeySet() and other methods. The enhanced ConcurrentHashMap is more suitable for use as a cache implementation class.

Note:
When using Collection under the java.util package as a collection object, if the collection object creates an iterator collection element changes, a ConcurrentModificationException will be thrown.

Since the bottom layer of CopyOnWriteArraySet encapsulates CopyOnWriteArrayList, its implementation mechanism is completely similar to CopyOnWriteList collection.

Corresponding to the CopyOnWriteArrayList collection, as its name implies, it uses the method of copying the underlying array to implement write operations.

When a thread performs a read operation on the CopyOnWriteArrayList collection, the thread will directly read the collection itself, without locking and blocking. When a thread performs a write operation on the CopyOnWriteArrayList collection (including calling add(), remove(), set(), etc.), the collection will copy a new array at the bottom layer, and then perform write operations on the new array . Since write operations to the CopyOnWriteArrayList collection are performed on copies of the array, it is thread-safe.

It should be pointed out that because CopyOnWriteArrayList needs to frequently copy the array when performing write operations, the performance is relatively poor, but because the read operation and the write operation are not the same array, and the read operation does not need to be locked, the read operation is very fast ,very safe. It can be seen that CopyOnWriteArrayList is suitable for use in scenarios where read operations are much larger than write operations, such as caching.

Guess you like

Origin blog.csdn.net/gaolh89/article/details/104852565