当前位置: 首页 > news >正文

【多线程】用阻塞队列实现等待唤醒机制(Java实现)

本文讲解一下 用阻塞队列实现等待唤醒机制,一路同行的小伙伴,如果对你有帮助,点赞、收藏、关注,谢谢~

1.什么是等待-唤醒机制?

多线程编程线程间通信的重要方式。
它允许线程在特定条件下主动等待,并在条件满足时被其他线程唤醒。

  • 一个线程检查某个条件,如果不满足就进入等待状态(阻塞)
  • 另一个线程修改条件后通知(唤醒) 等待的线程
  • 被唤醒的线程重新检查条件,如果满足就继续执行

2.为什么需要这种机制?

  • 避免忙等待(不断循环检查条件)节省CPU资源
  • 实现线程间的协调配合
  • 解决生产者-消费者等经典并发问题

3.用阻塞队列实现等待唤醒机制Demo:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class ProducerConsumerDemo {public static void main(String[] args) {// 创建一个容量为3的阻塞队列BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);// 生产者线程Thread producer = new Thread(() -> {try {for (int i = 1; i <= 5; i++) {String item = "Item-" + i;queue.put(item); // 将数据放入队列System.out.println("生产: " + item);Thread.sleep(500); // 模拟生产耗时}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});// 消费者线程Thread consumer = new Thread(() -> {try {for (int i = 1; i <= 5; i++) {String item = queue.take(); // 从队列取出数据System.out.println("消费: " + item);Thread.sleep(1000); // 模拟消费耗时}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});// 启动线程producer.start();consumer.start();}
}

3.1阻塞队列的作用:

BlockingQueue是一个线程安全的队列。

  • 当队列满时,put()操作会阻塞生产者线程,直到队列有空位
  • 当队列空时,take()操作会阻塞消费者线程,直到队列有新元素

3.2生产者线程逻辑:

  • queue.put(item): 尝试将item放入队列

    • 如果队列未满,直接放入
    • 如果队列已满,线程会被阻塞,直到队列有空位
  • Thread.sleep(500): 模拟生产每个item需要500ms

3.3消费者线程逻辑:

  • queue.take():尝试从队列取出元素

    • 如果队列不为空,直接取出
    • 如果队列为空,现成会被阻塞,直到队列有新元素
  • Thread.sleep(1000):模拟消费每个item需要1000ms

反正
生产者不需要关心消费者是否存在,只需往队列放数据
消费者不需要关心生产者是否存在,只需从队列取数据
阻塞队列自动处理了线程间的等待和唤醒,简化了并发编程

以上例子就是用阻塞队列实现等待唤醒机制,生产者存数据,消费者取数据。阻塞队列负责数据的暂时存储,处理线程的等待和唤醒。
如果对小伙伴有帮助,可以点赞、收藏、关注,谢谢~

http://www.xdnf.cn/news/329995.html

相关文章:

  • Python中的global与nonlocal关键字详解
  • 【软件测试学习day6】WebDriver常用的API
  • Java后端开发day43--IO流(三)--缓冲流转换流序列化流
  • 如何在本地测试网站运行情况
  • Kubernetes生产实战:容器内无netstat时的7种端口排查方案
  • 如何理解参照权
  • 如何设置飞书多维表格,可以在扣子平台上使用
  • Python办公自动化应用(三)
  • 备注在开发中的重要作用
  • MySQL数据库高可用(MHA)详细方案与部署教程
  • 国标GB28181视频平台EasyGBS打造电力行业变电站高效智能视频监控解决方案
  • 统计匹配的二元组个数 - 华为OD机试真题(A卷、JavaScript题解)
  • 宝塔面板,删除项目后还能通过域名进行访问
  • 从人脸扫描到实时驱动,超写实数字分身技术解析
  • Go语言中的并发编程--详细讲解
  • 【赵渝强老师】TiDB的备份恢复策略
  • 将本地项目提交到新建的git仓库
  • 【性能工具】一种简易hook bitmap创建的插件使用
  • Docker + Watchtower 实现容器自动更新:高效运维的终极方案
  • 算法研习:最大子数组和问题深度剖析
  • YOLO-POSE 姿态扩充
  • CUDA:out of memory的解决方法(实测有效)
  • 心智领航・数启未来 | AI数字化赋能精神心理医疗学术大会重磅来袭,5月10日广州附医华南医院开启智慧对话!
  • 【C++贪心】P9344 去年天气旧亭台|普及
  • Spark处理过程-转换算子和行动算子
  • NumPy 2.x 完全指南【一】简介
  • 混淆矩阵(Confusion Matrix)
  • Qt开发经验 --- 避坑指南(5)
  • python打卡day18
  • Spring MVC中跨域问题处理