BlockingQueue blocking queue
Blocking queue, as its name implies, is a queue. Through a shared queue, data can be input from one end of the queue and output from the other end;
- When the queue is empty, the operation of getting elements from the queue will be blocked
- When the queue is full, adding elements from the queue will be blocked
- Threads trying to get elements from an empty queue will be blocked until other threads insert new elements into the empty queue
- Threads trying to add new elements to a full queue will be blocked until other threads remove one or more elements from the queue or completely empty, making the queue idle and adding new elements later
There are two common queues:
- First in first out (FIFO): the elements of the queue inserted first also get out of the queue first, which is similar to the function of queuing. To some extent, this queue also reflects a kind of fairness
- Last in first out (LIFO): the elements inserted later in the queue are out of the queue first. This kind of queue gives priority to the recent events (stack)
Arrayblockingqueue (common)
Bounded blocking queue composed of array structure
BlockingQueue core method
case
public class BlockingQueueDemo { public static void main(String[] args) throws InterruptedException { //Create a blocking queue with a length of 3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3); // LinkedBlockingDeque<String> blockingDeque = new LinkedBlockingDeque<>(3); //Add first set of queues System.out.println(blockingQueue.add("a")); System.out.println(blockingQueue.add("b")); System.out.println(blockingQueue.add("c")); System.out.println(blockingQueue.element()); //System.out.println(blockingQueue.add("d"));// When the queue size is 3, add the fourth element and throw an exception System.out.println(blockingQueue.remove());//a System.out.println(blockingQueue.remove());//b System.out.println(blockingQueue.remove());//c // System.out.println(blockingQueue.remove());// abnormal //Add a second set of queues System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); // System.out.println(blockingQueue.offer("d"));// When the queue size is 3, add the fourth element and throw an exception System.out.println(blockingQueue.poll());//a System.out.println(blockingQueue.poll());//b System.out.println(blockingQueue.poll());//c // System.out.println(blockingQueue.poll());// abnormal //Group 3 blockingQueue.put("a"); blockingQueue.put("b"); blockingQueue.put("c"); // blockingQueue.put("d");// No exception will be thrown, and the thread is automatically in the waiting blocking state System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); // System.out.println(blockingQueue.take());// No exception will be thrown. When there is no queue in the thread, the queue cannot be retrieved, so it is in a blocked state //Group 4 System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); //Set the blocking time, 3L is the time length, timeunit Seconds is the unit of time. If it fails to enter the queue within 3S, it will end automatically System.out.println(blockingQueue.offer("d",3L, TimeUnit.SECONDS)); } }
Linkedblockingqueue (common)
ArrayBlockingQueue and LinkedBlockingQueue are the two most common and commonly used blocking queues. In general, using these two classes is sufficient to deal with producer consumer problems between multiple threads.
A bounded (but the default size is integer.MAX_VALUE) blocking queue composed of a linked list structure
public class BlockingQueueDemo { public static void main(String[] args) throws InterruptedException { //Create a blocking queue with a length of 3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3); // LinkedBlockingDeque<String> blockingDeque = new LinkedBlockingDeque<>(3); //Add first set of queues System.out.println(blockingQueue.add("a")); System.out.println(blockingQueue.add("b")); System.out.println(blockingQueue.add("c")); System.out.println(blockingQueue.element()); //System.out.println(blockingQueue.add("d"));// When the queue size is 3, add the fourth element and throw an exception System.out.println(blockingQueue.remove());//a System.out.println(blockingQueue.remove());//b System.out.println(blockingQueue.remove());//c // System.out.println(blockingQueue.remove());// abnormal //Add a second set of queues System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); // System.out.println(blockingQueue.offer("d"));// When the queue size is 3, add the fourth element and throw an exception System.out.println(blockingQueue.poll());//a System.out.println(blockingQueue.poll());//b System.out.println(blockingQueue.poll());//c // System.out.println(blockingQueue.poll());// abnormal //Group 3 blockingQueue.put("a"); blockingQueue.put("b"); blockingQueue.put("c"); // blockingQueue.put("d");// No exception will be thrown, and the thread is automatically in the waiting blocking state System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); // System.out.println(blockingQueue.take());// No exception will be thrown. When there is no queue in the thread, the queue cannot be retrieved, so it is in a blocked state //Group 4 System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); //Set the blocking time, 3L is the time length, timeunit Seconds is the unit of time. If it fails to enter the queue within 3S, it will end automatically System.out.println(blockingQueue.offer("d",3L, TimeUnit.SECONDS)); } }
summary
1. In the field of multithreading: the so-called blocking will suspend the thread (i.e. blocking) in some cases. Once the conditions are met, the suspended thread will be automatically aroused
2. Why do I need BlockingQueue? Before the release of concurrent package, in a multithreaded environment, each programmer must control these details, especially considering efficiency and thread safety, which will bring great complexity to our program. After use, we don't need to care about when to block the thread and when to wake up the thread, because all this is done by BlockingQueue