Java Concurrency Basics as I Understand (6): Concurrent Containers and Queues

JUC includes many container tools commonly used in concurrency, such as ConcurrentHashMap and CopyOnWriteArrayList. Queue is very important in concurrency, and there are many types, so this article lists the queues separately and does not count them in the container class.

1, ConcurrentHashMap, concurrent Map. The most commonly used concurrent container in concurrent programming. The underlying implementation in JDK1.8 is different from previous versions. The API usage is the same as java.lang.HashMap. It should be noted that HashMap supports null as a key, while ConcurrentHashMap does not, and a null pointer exception will be reported. ConcurrentHashMap does not have a FailFast mechanism when traversing.

2. CopyOnWriteArrayList, a List that supports concurrent reading and writing. The API usage is the same as java.lang.ArrayList. Allows one thread to write and multiple threads to read at the same time. CopyOnWriteArrayList does not have a FailFast mechanism when traversing.

Queues are structures that often appear in concurrency. Queues include blocking queue BlockingQueue, double-ended blocking queue BlockingDequeue, concurrent queue (non-blocking) ConcurrentLinkedQueue, etc. Follow the FIFO first-in, first-out principle.

The commonly used APIs of the BlockingQueue interface are as follows:

boolean add(E e); // 增加元素。如果队列已满,抛IllegalStateException异常
void put(E e) throws InterruptedException; // 增加元素。如果队列已满,则阻塞等待。阻塞期间响应线程中断异常。
boolean offer(E e); // 增加元素。如果队列已满,直接返回false。
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException // 增加元素。如果队列已满,则阻塞等待一段时间。阻塞期间响应线程中断异常。返回值同offer(E e)

boolean remove(Object o); // 删除指定元素。如果队列发生了改变,则返回true。
E take() throws InterruptedException; // 获取元素。如果队列为空则阻塞等待。阻塞期间响应线程中断异常。
E poll(long timeout, TimeUnit unit) throws InterruptedException; // 指定时间内阻塞等待获取元素。如果队列为空则阻塞等待。阻塞期间响应线程中断异常。
boolean contains(Object o); // 队列中是否包含指定元素

int remainingCapacity(); // 队列还能存放多少个元素,返回值 = 初始化总数 - 以存放个数

The implementation classes of the BlockingQueue interface are: ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, PriorityBlockingQueue, and SynchronousQueue.

1, ArrayBlockingQueue, array blocking queue. ArrayBlockingQueue is a bounded blocking queue, and the constructor can specify whether it is fair or not. Its internal implementation is to put objects into an array. Bounded also means that it cannot store an infinite number of elements. It has an upper limit on the number of elements that can be stored at one time. You can set this upper limit when it is initialized, but it cannot be modified after that ). ArrayBlockingQueue internally stores elements in FIFO (first-in, first-out) order. The head element in the queue is the one with the longest time among all the elements, and the tail element is the one with the shortest time.

2, DelayQueue, delay queue. DelayQueue holds elements until a specific delay expires. Elements injected into it must implement the java.util.concurrent.Delayed interface. The interface inherits the java.lang.Comarable comparator interface, as follows:

public interface Delayed extends Comparable<Delayed> {
    long getDelay(TimeUnit unit);
}

DelayQueue will be added to the queue after the time period of the value returned by each element's getDelay() method. If it returns 0 or a negative value, it will be added to the queue directly.

3, LinkedBlockingQueue, linked list blocking queue. LinkedBlockingQueue is the most efficient blocking queue with the highest appearance rate, and its elements are stored in a chain structure (link node) internally. If desired, an upper limit can be chosen for this chain structure. If no upper limit is defined, Integer.MAX_VALUE will be used as the upper limit.

4, PriorityBlockingQueue, priority queue. PriorityBlockingQueue is an unbounded concurrent queue. It uses the same ordering rules as ava.util.PriorityQueue. All elements inserted into the PriorityBlockingQueue must implement the java.lang.Comparable interface, because the priority comparison of elements is done through the Comparable interface. The ordering of the elements in the column is up to your own Comparable implementation. Tips: The Iterator returned from the PriorityBlockingQueue queue does not guarantee that the traversal of the elements is in the priority order of the elements.

5, SynchronousQueue, synchronous queue. SynchronousQueue is a special queue that can only hold one element at a time. If the queue already has an element, a thread attempting to insert a new element into the queue will block until another thread removes the element from the queue. Likewise, if the queue is empty, a thread attempting to extract an element from the queue will block until another thread inserts a new element into the queue.

6, LinkedTransferQueue, unbounded linked list queue. Compared with LinkedBlockingQueue, there are more tryTransfer and transfer methods.

void transfer(E e) throws InterruptedException // 如果有线程在阻塞等待回去元素,则直接将e传递给等待的线程。如果没有则阻塞等待线程来获取元素。阻塞期间响应线程中断异常。(违反了FIFO原则)
boolean tryTransfer(E e, long timeout, TimeUnit unit)throws InterruptedException // 一段时间内阻塞等待线程获取元素,作用同transfer(E e)。如果超时则返回false。

BlockingDeque is a double-ended blocking queue interface that allows elements to be added and retrieved at both ends of the queue. Inherit class BlockingQueue interface, but it is not recommended to use BlockingQueue related API. The commonly used APIs of BlockingDeque are as follows:

//在头部操作
boolean addFirst(E e); // 同BlockingQueue的add(E e)
void putFirst(E e) throws InterruptedException; // 同BlockingQueue的put(E e)
boolean offerFirst(E e); // 同BlockingQueue的offer(E e)
boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException // 同BlockingQueue的offer(E e, long timeout, TimeUnit unit)
boolean removeFirstOccurrence(Object o); // 从头部开始删除第一个相同的元素。同BlockingQueue的remove(E e)
E takeFirst() throws InterruptedException; // 同BlockingQueue的take()
E pollFirst(long timeout, TimeUnit unit) throws InterruptedException; // 同BlockingQueue的poll()


// 在尾部操作
boolean addLast(E e); // 同BlockingQueue的add(E e)
void putLast(E e) throws InterruptedException; // 同BlockingQueue的put(E e)
boolean offerLast(E e); // 同BlockingQueue的offer(E e)
boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException // 同BlockingQueue的offer(E e, long timeout, TimeUnit unit)
boolean removeLastOccurrence(Object o); // 从尾部开始删除第一个相同的元素。同BlockingQueue的remove(E e)
E takeLast() throws InterruptedException; // 同BlockingQueue的take()
E pollLast(long timeout, TimeUnit unit) throws InterruptedException; // 同BlockingQueue的poll()

7, LinkedBlockingDeque, linked list double-ended blocking queue. The only class that implements the BlockingDeque interface in the JUC package. Its implementation is the same as LinkedBlockingQueue. When the linked list is empty, a thread trying to extract data from it will block, regardless of which end the thread is trying to extract from. It is recommended to use Deque for polymorphic API operations.

8, ConcurrentLinkedQueue, concurrent non-blocking security queue. ConcurrentLinkedQueue implements the Queue interface and is an unbounded queue based on a linked list. It follows the FIFO first-in-first-out principle and uses a circular CAS method to achieve non-blocking concurrency security. It is recommended to use Queue for API operations in polymorphic form.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324931891&siteId=291194637