Java多线程:阻塞队列与等待唤醒机制初探
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程:阻塞队列与等待唤醒机制初探相关的知识,希望对你有一定的参考价值。
文章目录
阻塞队列概述
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
阻塞队列基本使用
BlockingQueue
常见BlockingQueue有:
- ArrayBlockingQueue: 底层是数组,有界
- LinkedBlockingQueue: 底层是链表,无界.但不是真正的无界,最大为int的最大值
他们两个和List的实现子类有点像。
他们的继承结构如下:
BlockingQueue的核心方法:
核心方法:
方法 | 说明 |
---|---|
put(anObject) | 将参数放入队列,如果放不进去会阻塞 |
take() | 取出第一个数据,取不到会阻塞 |
其他方法(与List类似)
方法\\处理方式 | 抛出异常 | 返回特殊值 | 一直阻塞 | 超时退出 |
---|---|---|---|---|
插入方法 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除方法 | remove() | poll() | take() | poll(time,unit) |
检查方法 | element() | peek() | 不可用 | 不可用 |
多线程一般多用put与take
代码示例
class Demo02
public static void main(String[] args) throws Exception
// 创建阻塞队列的对象,容量为 1
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
// 存储元素
arrayBlockingQueue.put("糖果");
// 取元素
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take()); // 取不到会阻塞
System.out.println("程序结束了");
程序没有结束,他会一直读取阻塞队列
阻塞队列实现等待唤醒机制
代码需求:
生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务
- 构造方法中接收一个阻塞队列对象
- 在run方法中循环向阻塞队列中添加包子
- 打印添加结果
消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务
- 构造方法中接收一个阻塞队列对象
- 在run方法中循环获取阻塞队列中的包子
- 打印获取结果
测试类(Demo):里面有main方法,main方法中的代码步骤如下
- 创建阻塞队列对象
- 创建生产者线程和消费者线程对象,构造方法中传入阻塞队列对象
- 分别开启两个线程
代码示例
package com.test;
import java.util.concurrent.ArrayBlockingQueue;
class Cooker extends Thread
private ArrayBlockingQueue<String> bd;
public Cooker(ArrayBlockingQueue<String> bd)
this.bd = bd;
@Override
public void run()
while (true)
try
bd.put("糖果");
System.out.println("厨师放入一个糖果");
catch (InterruptedException e)
e.printStackTrace();
class Foodie extends Thread
private ArrayBlockingQueue<String> bd;
public Foodie(ArrayBlockingQueue<String> bd)
this.bd = bd;
@Override
public void run()
while (true)
try
String take = bd.take();
System.out.println("吃货将" + take + "拿出来吃了");
catch (InterruptedException e)
e.printStackTrace();
class Demo
public static void main(String[] args)
// 一个阻塞队列代表一个桌子
ArrayBlockingQueue<String> bd = new ArrayBlockingQueue<>(1);
Foodie f = new Foodie(bd);
Cooker c = new Cooker(bd);
f.start();
c.start();
以上是关于Java多线程:阻塞队列与等待唤醒机制初探的主要内容,如果未能解决你的问题,请参考以下文章
阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第4节 等待唤醒机制_7_等待唤醒机制需求分析
阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第4节 等待唤醒机制_8_等待唤醒机制代码实现_包子类&包子铺类