Concurrent containers (copying papers)



Description: equal to reprint blog, from JavaGuide (or have their own manual of practice again)


1. Overview

Concurrent containers JDK provided in java.util.concurrent, that famous JUC, are:

  • ConcurrentHashMap: HashMap thread-safe
  • CopyOnWriteArrayList: thread-safe list
  • ConcurrentLinkedQueue: Efficient concurrent queue, and queue, stack Comparison
  • BlockingQueue: the interface: implemented by a linked list, an array, etc., represent blocking queue for the shared data channel
  • ConcurrentSkipListMap: jump table implementation, which is a Map, data structures used for rapid lookup table jump








2. ConcurrentHashMap

CAS uses concurrency and synchronized to ensure safety, the difference is only locked when writing the first node, as long as a collision does not occur, it will not concurrent, compared to the previous segment improved concurrency. Use bottom: Node array + list / black tree








3. CopyOnWriteArrayList

Daily, we read many of which are accounted for a large part, but write less. If every time a read operation lock is a waste, so we allow concurrent access to multiple threads to read the data, but also write without blocking read operation, write and write and only need to synchronize wait.


CopyOnWrite: After the computer, if you want to modify a block of memory, we are not in the original block of memory is written, but the memory copy, the new in-memory write operation, finish it, to will point to the original memory pointer to the new memory, the original memory can be recovered out


All variable operating CopyOnWriteArrayList class (add, set, etc.) are by creating a new copy of the underlying array to achieve. At the name: when writing copy. When the List need to be modified, I do not modify the original content, but a copy of the original data, the changes have been written copies. After writing, then revised and replaced the original copy of data, so that you can ensure that write operations do not affect the read operation


For example, when writing add method

public boolean add(E e) {
    
    // 需要手动的锁机制,并发知识
    final ReentrantLock lock = this.lock;
    lock.lock();
    
    try {
        // 这里其实看代码就能知道怎么回事了
        Object[] elements = getArray();
        int len = elements.length;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}

Note: When replication is required locked, avoid multi-threading multiple copies out








Providing thread-safe Queue Java can be divided into blocking queue and non-blocking queue , which is a typical example of blocking queue BlockingQueue, a typical example of non-blocking queue is ConcurrentLinkedQueue, in practical applications according to the actual need to use blocking or non-blocking queue queue . Queues may be achieved by blocking lock, CAS may be implemented by non-blocking operation queue.

4. ConcurrentLinkedQueue

Its internal use of CAS is implemented for multi-threaded access the queue, and the high cost of locking time. As I review the content when CAS belong concurrent locks, and so on back to write a blog to introduce








We have already mentioned above as a high-performance non-blocking ConcurrentLinkedQueue queue. Now we want to address is blocking queue --BlockingQueue. Blocking queue (BlockingQueue) is widely used in "producer - consumer" problem, the reason is BlockingQueue provides a method of insertion and removal can be blocked. When the queue container is full, the producer thread will be blocked until the queue is not full; when the queue is empty the container, the consumer thread is blocked, up until the queue is not empty

5. BlockingQueue

BlockingQueue is an interface, inherited from the Queue, so its implementation class can also be used as an implementation of the Queue, and Queue also inherited from the Collection interface. Here is BlockingQueue related implementation class:

  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • PriorityBlockingQueue


5.2 ArrayBlockingQueue

ArrayBlockingQueue is bounded queue BlockingQueue interface implementation class, using the underlying array is achieved. ArrayBlockingQueue Once created, the capacity can not be changed . Using concurrency control which reentrant lock controls, whether an insert operation or a read operation, all need to acquire the lock to operate. When the queue is full capacity, try to put into the queue will cause the operating element blocking; attempt to remove an element from an empty queue will also block

ArrayBlockingQueue default can not guarantee the fairness of the threads access the queue, the so-called fairness refers to the absolute chronological order in strict accordance waiting threads that can wait for the first thread first visit to ArrayBlockingQueue. Rather than fairness refers to the sequential access ArrayBlockingQueue not comply with a strict chronological order, there may exist when ArrayBlockingQueue can be accessed, for a long time blocked thread is still inaccessible to ArrayBlockingQueue. If the guarantee fairness, generally decreases throughput. If you need ArrayBlockingQueue fairness, may be employed the following code:

private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);


5.3 LinkedBlockingQueue

LinkedBlockingQueue bottom on a one-way linked list implementation blocking queue can queue as unbounded queue may be used as bounded , to meet the same characteristics of the FIFO, with higher throughput compared with ArrayBlockingQueue with them, in order to prevent the rapid increase in the capacity LinkedBlockingQueue loss a lot of memory. When you create an object usually LinkedBlockingQueue will specify the size, if not specified, the capacity is equal to Integer.MAX_VALUE


5.4 PriorityBlockingQueue

PriorityBlockingQueue is a priority - unbounded blocking queue. By default sort order using natural elements, may be implemented by a custom class compareTo()to specify the elements of collation methods, or by constructing the initialization parameters Comparatorspecified collation.

PriorityBlockingQueue concurrency control uses of ReentrantLock , the queue is unbounded queue (ArrayBlockingQueue with queue is bounded, a LinkedBlockingQueue capacity may be specified by the incoming queue maximum capacity in the constructor, but only specify the initial PriorityBlockingQueue queue size, the element inserted behind when, if space is not enough, then automatically expansion ).

Simply put, it is the thread-safe version of PriorityQueue. Can not insert a null value, while the object is inserted into the queue must be of comparable size (Comparable), or abnormal ClassCastException reported. It put the insertion method does not block, because it is unbounded queue (take method will be empty when the queue is blocked).








6. ConcurrentSkipListMap

In order to elicit ConcurrentSkipListMap, to bring everyone to understand what a simple jump table.

For a single linked list, even if the list is ordered, if we want to find a data which can only traverse the list from start to finish, so that efficiency will naturally low, jump table is not the same. Jump table is a data structure that can be used to quickly find, somewhat similar to balanced trees. They can quickly find the elements. However, an important difference is: for a balanced tree insertion and deletion are often likely to lead to a balanced tree once the global adjustment. While hop insert and delete table only needs to operate the whole of the local data structure. Such benefits are: in the case of high concurrency, you'll need a global lock to guarantee thread safety throughout the balance of the tree. For jump table, you only need to lock part. Thus, in a highly concurrent environment, you can have better performance. And in terms of query performance, time complexity jump table is O (logn) so concurrent data structures, JDK using a jump table to achieve a Map


Nature jump table is at the same time maintain multiple lists, and the list is hierarchical,

The lowest level to maintain the list of all the elements in the jump table, each top layer is a layer of a subset of the list below.

All the elements of the list in the jump table is sorted. When the search, you can find the list starting from the top. Once the element being sought is greater than the current value of the list, the list will be transferred to the next level, keep looking. This means that during the search, the search is leaps and bounds. As shown above, the elements 18 find the jump table.

Find 18 when the original need to traverse 18, now only takes seven times. For the length of the list when large build an index seek to enhance the efficiency will be very obvious.

Readily seen from the above, the jump table is a use of space for time algorithm.

Use jump table implementation is another difference between the Map and Map hash algorithm is: hash does not save order of the elements, and all elements in the jump table is sorted. Therefore, when to jump to traverse the table, you'll get an ordered result. So, if your application requires orderly, then jump table is your only choice. This data structure is implemented JDK classes are ConcurrentSkipListMap.




Guess you like

Origin www.cnblogs.com/Howlet/p/12517439.html