Multithreading - blocking queue

Basic usage of blocking queue:

Common blocking queues are ArrBlockingQueue and LinkedBlockQueue

Here is their inheritance structure:

 

 

  • ArrayBlockingQueue: The bottom layer is an array, bounded
  • LinkedBlockingQueue: The bottom layer is a linked list, unbounded. But not really unbounded, the maximum is the maximum value of int

From the inheritance mechanism of Blockqueue, it can be seen that they are actually a single-column collection, so the methods in the collection can be used:

  • put(anObject): put the parameter into the queue, it will block if you don't put it in
  • take(): take out the first data, it will block if not taken
  • When creating a Blockqueue, fill in an int number in the constructor to represent the maximum number of elements the blocking queue can hold

Blocking simple code is as follows:

 1 public class Demo02 {
 2     public static void main(String[] args) throws Exception {
 3         // Object that creates a blocking queue,capacity is 1
 4         ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
 5 
 6         // storage element
 7         arrayBlockingQueue.put("hamburger");
 8 
 9         // take element
10         System.out.println(arrayBlockingQueue.take());
11         System.out.println(arrayBlockingQueue.take()); // Can't get it will block
12 
13         System.out.println("program is over");//The program will not execute here
14     }
15 }

 

 

Write a case below to help understand:

  • Case requirements

Producer class (Cooker): Implement the Runnable interface, override the run() method, and set thread tasks

1. Receive a blocking queue object in the constructor

2. Loop adding buns to the blocking queue in the run method

3. Print the result of adding

Consumer class (Foodie): Implement the Runnable interface, override the run() method, and set thread tasks

1. Receive a blocking queue object in the constructor

2. Loop to get the buns in the blocking queue in the run method

3. Print the result

Test class (Demo): There is a main method in it. The code steps in the main method are as follows

1. Create a blocking queue object

2. Create producer thread and consumer thread objects, and pass in the blocking queue object in the constructor

3. Open two threads separately

Code:

 1 public class Cooker extends Thread {
 2 
 3     private ArrayBlockingQueue<String> bd;
 4 
 5     public Cooker(ArrayBlockingQueue<String> bd) {
 6         this.bd = bd;
 7     }
 8 //    Producer step:
 9 //            1,Determine if there is a hamburger on the table
10 //    If there is, wait, if not, then produce.
11 //            2,Put the hamburger on the table.
12 //            3,Wake up waiting consumers to start eating.
13 
14     @Override
15     public void run() {
16         while (true) {
17             try {
18                 bd.put("hamburger");
19                 System.out.println("Chef puts in a hamburger");
20             } catch (InterruptedException e) {
21                 e.printStackTrace();
22             }
23         }
24     }
25 }
26 
27 public class Foodie extends Thread {
28     private ArrayBlockingQueue<String> bd;
29 
30     public Foodie(ArrayBlockingQueue<String> bd) {
31         this.bd = bd;
32     }
33 
34     @Override
35     public void run() {
36 //        1,Determine if there is a hamburger on the table.
37 //        2,If not just wait.
38 //        3,Eat if you have it
39 //        4,After eating, there are no hamburgers on the table
40 //                Wake up waiting producers to resume production
41 //        Reduce the total number of hamburgers by one
42 
43         //routine:
44         //1. while(true)infinite loop
45         //2. synchronized Lock,The lock object must be unique
46         //3. judge,Does sharing data end?. Finish
47         //4. judge,Does sharing data end?. not end yet
48         while (true) {
49             try {
50                 String take = bd.take();
51                 System.out.println("foodie will" + take + "take it out and eat it");
52             } catch (InterruptedException e) {
53                 e.printStackTrace();
54             }
55         }
56 
57     }
58 }
59 
60 public class Demo {
61     public static void main(String[] args) {
62         ArrayBlockingQueue<String> bd = new ArrayBlockingQueue<>(1);
63 
64         Foodie f = new Foodie(bd);
65         Cooker c = new Cooker(bd);
66 
67         f.start();
68         c.start();
69     }
70 }

 

Note: There will be two times of eating and drinking in the running results. The reason is: the code of eating and drinking makes our own writing without lock, and the program execution is done or eaten.

However, when it is running to do or eat, the CPU may execute another thread, resulting in repetition, but in fact it is doing one and eating one, and doing one and eating one.

 

Tags: Java

Posted by Dasndan on Sun, 22 May 2022 07:20:18 +0300