阅读此篇文章请先了解
一、ArrayBlockingQueue介绍
ArrayBlockingQueue是一个用数组实现的有界阻塞队列。此队列按照先进先出(FIFO)的原则对元素进行排序。
类图结构如下:
二、原理分析
2.1 示例代码
设计目的:做个线程从阻塞队列中,获取元素或者放入元素,同一直接只有一个线程进行(获取或放入操作)。
代码
生产者Producer.java
1 public class Producer implements Runnable { 2 private BlockingQueue<Integer> numbersQueue; 3 4 public Producer(BlockingQueue<Integer> numbersQueue) { 5 this.numbersQueue = numbersQueue; 6 } 7 public void run() { 8 try { 9 while(true){ 10 int num = ThreadLocalRandom.current().nextInt(100); 11 numbersQueue.put(num); 12 System.out.printf("%s:将%d号球放入队列中,存在%d个球\n",Thread.currentThread().getName(), num, numbersQueue.size()); 13 Thread.sleep(10); 14 } 15 } catch (InterruptedException e) { 16 Thread.currentThread().interrupt(); 17 } 18 } 19 }
消费者:Consumer.java
1 public class Consumer implements Runnable { 2 3 private BlockingQueue<Integer> numbersQueue; 4 5 6 7 public Consumer(BlockingQueue<Integer> numbersQueue) { 8 this.numbersQueue = numbersQueue; 9 } 10 public void run() { 11 try { 12 while(true){ 13 14 // while (TestDemo.flag != 1) { 15 // try { 16 // Thread.sleep(1000); 17 // } catch (InterruptedException e) { 18 // e.printStackTrace(); 19 // } 20 // } 21 22 // 消费 23 Integer num = numbersQueue.take(); 24 System.out.printf("%s:将%d号球从队列中取出,队列中还存在%d个球\n", Thread.currentThread().getName() ,num, numbersQueue.size()); 25 26 Thread.sleep(10); 27 28 } 29 } catch (InterruptedException e) { 30 Thread.currentThread().interrupt(); 31 } 32 } 33 }
测试TestDemo.java
1 public class TestDemo { 2 3 public static volatile int flag = 0; 4 5 public static void main(String[] args) { 6 7 int BOUND = 10; 8 int N_PRODUCERS = 10; 9 int N_CONSUMERS = 10; 10 11 BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(BOUND); 12 13 for (int i = 0; i < N_PRODUCERS; i++) { 14 new Thread(new Producer(queue), "生产者" + i).start(); 15 } 16 17 for (int j = 0; j < N_CONSUMERS; j++) { 18 new Thread(new Consumer(queue), "消费者" + j).start(); 19 } 20 21 22 // 控制消费者 23 // 输入不等于1 继续等待 24 Scanner scanner = new Scanner(System.in); 25 while (true) { 26 try { 27 flag = scanner.nextInt(); 28 Thread.sleep(1000); 29 } catch (InterruptedException e) { 30 e.printStackTrace(); 31 } 32 } 33 } 34 35 }
2.1 原理图
1、put(e) 与 take() 流程图
2、阻塞队列状态图