Concurrent queues: practical application scenarios and principles of ArrayBlockingQueue

table of Contents

 

Practical application scenarios of ArrayBlockingQueue

ArrayBlockingQueue simplified class diagram structure

Concurrent queue blocking and non-blocking concepts

Non-blocking

block

Analysis of the realization principle of ArrayBlockingQueue

Completely non-blocking queue ConcurrentLinkedQueue

List multi-threaded safety scheme: LinkedBlockingQueue

to sum up


Practical application scenarios of ArrayBlockingQueue


I have done an emotion recognition system in a company before. This system collects facial information by calling the camera interface, performs facial recognition and emotion analysis on the collected facial information, and finally converts personal emotion data into specific behaviors through a certain algorithm Index value. The concurrent queue ArrayBlockingQueue is used in the part of collecting pictures.

image.png

As shown in the above figure: there are n cameras, and the efficiency of single-threaded collection will be slow. Therefore, the process of collecting cameras is multi-threaded. In addition, the collected pictures need to be stored in the picture server, and the writing to the picture server is also very high. It is required that the image server is clustered, and it also needs to be multi-threaded. After the image is stored in the database, the image data needs to be sent to the face analysis server for processing. This part involves distributed messages, so the black dashed part uses kafka to transmit the message. Among them, the red dotted line part of the multi-threaded image collection transfers information to the multi-threaded image storage uses ArrayBlockingQueue , which is a concurrent safe queue .

 

ArrayBlockingQueue simplified class diagram structure


image.png

It can be seen from the class diagram that the Queue interface provides methods for adding and offering into the queue, and methods for polling out of the queue!

The BlockingQueue interface adds a put method to the queue and a method to take out of the queue!

Supplementary explanation: UML class diagram structure:

  • Inheritance: solid line and empty arrow.
  • Realization: dashed dotted arrow.

 

 

Concurrent queue blocking and non-blocking concepts


From the name of the class diagram above, you can see that the method provided by Queue is non-blocking! The BlockingQueue provided PUT, the Take method is blocked! Following the old ideas, we use code to illustrate blocking and non-blocking !

Non-blocking

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @author :jiaolian
 * @date :Created in 2021-02-02 20:16
 * @description:ArrayBlockingQueue阻塞非阻塞测试
 * @modified By:
 * 公众号:叫练
 */
public class ArrayBlockingQueueTest {
    public static void main(String[] args) {
        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
        arrayBlockingQueue.offer("叫练");
        arrayBlockingQueue.offer("叫练");
        //输出arrayBlockingQueue的长度
        System.out.println(arrayBlockingQueue.size());
    }
}

The above code: Set the length of ArrayBlockingQueue to 1, add 2 elements to the queue through the offer method, and finally print the length of arrayBlockingQueue? The answer is one, will not be blocked , because the offer method discards the second element, "called the practice", we say that the team and the team can continue to let the queue we call non-blocking . What if it is replaced by the add method? It will report an error that the queue overflows, as shown in the figure below! But it's not blocking yet. Let's see what is blocking!

image.png

 

block

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @author :jiaolian
 * @date :Created in 2021-02-02 20:16
 * @description:ArrayBlockingQueue阻塞非阻塞测试
 * @modified By:
 * 公众号:叫练
 */
public class ArrayBlockingQueueTest {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
        arrayBlockingQueue.put("叫练");
        arrayBlockingQueue.put("叫练");
        //输出arrayBlockingQueue的长度
        System.out.println(arrayBlockingQueue.size());
    }
}

The above code: The length of ArrayBlockingQueue is 1, and 2 elements are added to the queue through the put method. What is the length of the final output arrayBlockingQueue? The answer is that the console keeps running because the program is blocked when the second "calling practice" is added. We say that the team and the team can not be allowed to continue to implement our queue called blocking, the Add method, poll method, take the way we not one by one example, you can write code to do the simplest test!

 

Well, let's summarize a few methods!

  • Join the team:

offer: The queue is full and discarded.

add: The queue is full and an error is reported.

put: blocking.

  • Departure:

poll: If the queue is empty, it returns null.

take: blocking.

 

Analysis of the realization principle of ArrayBlockingQueue


image.png

As shown in the figure above, ArrayBlockingQueue is implemented with an array, and the ReentrantLock exclusive lock controls the enqueue and dequeue of the array. notEmpty and notFull are the two conditional queues of ReentrantLock, which are used to control whether the queue enters the blocking state. They are the producer and consumer models. Let's take a look at the process of take and put methods . The other methods are the same.

  • take method: multiple threads compete for exclusive lock to obtain the first element of the items[ taskIndex ] queue . Among them, thread A successfully acquires the lock, and other threads block and wait for the execution of the A thread to finish releasing the lock. If the queue is not empty, thread A acquires the items[ taskIndex ] element Return to remove and release the lock to let other blocked threads continue to compete; if the queue is empty, thread A calls the notEmpty.await method to enter the conditional queue and release the lock to let other blocked threads continue to compete, and other threads will also enter the notEmpty conditional queue when they find that the queue is empty , Waiting for the put thread to join the queue and notify notEmpty to block the thread.
  • put method: multiple threads compete for exclusive lock setting items[putIndex ] the tail element of the queue, where A thread successfully acquires the lock, other threads block and wait for the execution of A thread to finish releasing the lock, if the queue is not full [queue length], A thread adds items[ putIndex ] The element returns and releases the lock to let other blocked threads continue to compete; if the queue is full, the A thread calls the notFull.await method to enter the conditional queue and releases the lock to let other blocked threads continue to compete. Other threads will also enter the notFull conditional queue when they find that the queue is empty. , Waiting for the take thread to dequeue and notify notFull to block the thread .

 

Completely non-blocking queue ConcurrentLinkedQueue


ConcurrentLinkedQueue also implements the Queue interface, providing offer, add, and poll methods that are non-blocking. In addition, as can be seen from the name, the bottom layer is a linked list structure, and the enqueue and dequeue use spin cas.

 

 

List multi-threaded safety scheme: LinkedBlockingQueue


image.png

LinkedBlockingQueue is similar to ArrayBlockingQueue. LinkedBlockingQueue is bounded and the length is Integer.MAX_VALUE . In terms of implementation, LinkedBlockingQueue is a linked list and is double-locked. As shown in the figure above, takeLock exclusively controls the head of the queue, and putLock controls the tail of the queue, and does not affect each other. , The purpose is to improve the concurrency of LinkedBlockingQueue.

 

to sum up


Today we introduced several important concepts of concurrent queues. We have sorted them out and hoped to be helpful to you. The writing is not complete. At the same time, there are many things that need to be corrected. I hope you can correct and comment. These concepts of output thread pool and so on. Please like and pay attention to the ones you like. Pay attention, don’t get lost, I’m called Lian [ Official Account ] , and I’m calling while practicing.

8bcfc73380e185dcaf516ada1b44abd.jpg

 

Reference book: "The Beauty of Java Concurrent Programming"

 

 

 

Guess you like

Origin blog.csdn.net/duyabc/article/details/113585875