[concurrent programming] Introduction to blocking queue

What is BlockingQueue

  • BlockingQueue inherits the Queue interface and is a kind of Queue.
  • Blocking queue is a queue that supports two additional operations on the basis of queue. It is often decoupled.
  • Support blocking insert method put: when the queue is full, the queue will block the thread inserting elements until the queue is full.
  • take: when the queue is empty, the thread that gets the element will wait for the queue to become non empty.

The blocking Queue inherits the Queue interface

  • Add (E): add an element and return true after adding successfully. If the queue is full, an exception will be thrown.
  • Offer (E): if an element is added, true will be returned. If the queue is full, false will be returned.
  • remove(): returns and deletes the first element of the queue. If the queue is empty, an exception will be thrown.
  • poll(): returns and deletes the first element of the queue. If the queue is empty, null is returned.
  • element(): returns the first element of the queue without removing it. If the queue is empty, an exception will be thrown
  • peek(): get the queue head element without removing it. If the queue is empty, null will be returned

BlockingQueue common methods

method Throw exception Returns a specific value block Block specific time
Join the team add(e) offer(e) put(e) offer(e, time, unit)
Out of the team remove() poll() take() poll(time, unit)
Get team leader element element() peek() I won't support it I won't support it

Characteristics of blocking queue

  • The main feature that distinguishes blocking queues from other types of queues is the word "blocking"!
  • The blocking function balances the capabilities of producers and consumers. When either end is too fast, the blocking queue will reduce the too fast speed.
  • The two most important methods to implement blocking are take method and put method.

take method of blocking queue

  • The function of the take method is to obtain and remove the head node of the queue. Usually, it can be removed normally when there is data in the queue.
  • Once the take method is executed and there is no data in the queue, it will be blocked until there is data in the queue.
  • Once there is data in the queue, it will immediately remove the blocking state and get the data.

put method of blocking queue

  • When the put method inserts elements, if the queue is not full, it is the same as normal insertion.
  • If the queue is full, the insertion cannot continue, and blocking occurs until there is free space in the queue.
  • If the subsequent queue has free space, such as a consumer consuming an element, the queue will be unblocked and the data to be added will be added to the queue.

Boundary of blocking queue

  • Capacity can be divided into bounded and unbounded.
  • Unbounded queue means that it can hold many elements. For example, the upper limit of LinkedBlockingQueue is integer MAX_ Value is a very large number, which can be approximately regarded as infinite capacity, because we can hardly fill this capacity.
  • However, some blocking queues are bounded. For example, if the capacity of ArrayBlockingQueue is full, it will not be expanded, so once it is full, it can no longer put data into it.

Application scenario of blocking queue

  • BlockingQueue is thread safe and can solve thread safety problems.
  • Because the blocking queue is thread safe, both producers and consumers can be multithreaded without thread safety problems.
  • Producers / consumers can directly use thread safe queues without having to consider more thread safety issues themselves. This means that the task of considering thread safety issues such as locks has shifted from "you" to "queue", which reduces the difficulty and workload of our development.
  • Queue, which can also serve as an isolation. Producers do not need to pay attention to the logic of consumers. It realizes the decoupling between specific tasks and execution task classes, and improves the security.

Common blocking queue

  • ArrayBlockingQueue: a bounded blocking queue based on array structure.
  • LinkedBlockingQueue: an unbounded blocking queue based on linked list structure.
  • PriorityBlockingQueue: supports unbounded blocking queues sorted by priority.
  • DelayQueue: an unbounded blocking queue based on priority blocking queue.
  • SynchronousQueue: a blocking queue that does not store elements.
  • LinkedTransferQueue: an unbounded blocking queue based on linked list structure.
  • LinkedBlockingDeque: a double ended blocking queue based on linked list structure.

Verification method of blocking queue

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {
	public static void main(String[] args) {
		addTest();
		// removeTest();
		// elementTest()
		// offerTest()
		// pollTest()
		// peekTest()
		// putTest()
		// putTest()
	}

	/**
	 * add The method is to add an element to the queue. If the queue is full, an exception will be thrown to indicate that the queue is full.
	 */
	private static void addTest() {
		BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		System.out.println(blockingQueue.add(1));
		System.out.println(blockingQueue.add(2));
		System.out.println(blockingQueue.add(3));
	}

	/**
	 * remove Method is used to delete elements and return the header node of the queue. If the deleted queue is empty, the remove method will throw an exception.
	 */
	private static void removeTest() {
		ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		blockingQueue.add(1);
		blockingQueue.add(2);
		System.out.println(blockingQueue.remove());
		System.out.println(blockingQueue.remove());
		System.out.println(blockingQueue.remove());
	}

	/**
	 * element The method returns the head node of the queue, but does not delete it. If the queue is empty, an exception is thrown
	 */
	private static void elementTest() {
		ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		blockingQueue.element();
	}

	/**
	 * offer Method is used to insert an element. It returns true if the addition is successful, and false if the queue is full
	 */
	private static void offerTest() {
		ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		System.out.println(blockingQueue.offer(1));
		System.out.println(blockingQueue.offer(2));
		System.out.println(blockingQueue.offer(3));
	}

	/**
	 * poll The method also removes and returns the head node of the queue. If the queue is empty, null is returned
	 */
	private static void pollTest() {
		ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(3);
		blockingQueue.offer(1);
		blockingQueue.offer(2);
		blockingQueue.offer(3);
		System.out.println(blockingQueue.poll());
		System.out.println(blockingQueue.poll());
		System.out.println(blockingQueue.poll());
		System.out.println(blockingQueue.poll());
	}

	/**
	 * peek Method returns the header element of the queue but does not delete it. If the queue is empty, null is returned
	 */
	private static void peekTest() {
		ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		System.out.println(blockingQueue.peek());
	}

	/**
	 * put Method is used to insert elements. If the queue is full, the insertion cannot continue, and the insertion thread is blocked until the queue is empty
	 */
	private static void putTest() {
		BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		try {
			blockingQueue.put(1);
			blockingQueue.put(2);
			blockingQueue.put(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * take Method is used to get and remove the head node of the queue. If there is no data in the queue, block until there is data in the queue
	 */
	private static void takeTest() {
		BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(2);
		try {
			blockingQueue.take();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Concluding remarks

  • Get more pre knowledge articles of this article and new valuable articles. Let's become architects together!
  • Paying attention to the official account gives you a deep understanding of MySQL.
  • Pay attention to official account and keep continuous understanding of concurrent programming every day!
  • Pay attention to the official account, and follow the continuous and efficient understanding of spring source code.
  • This official account is not advertising!!! Update daily!!!

Keywords: Concurrent Programming

Added by dan231 on Fri, 04 Feb 2022 16:05:02 +0200