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

从“干瞪眼“到精准唤醒:Java线程通信的打怪升级之路

在Java的世界里,线程就像一群忙碌的工人。有时候,这些工人需要互相传递消息、协调工作进度,这就是线程通信要解决的问题。今天我们就来聊聊Java线程通信从古老的wait/notify,到现代化的Condition,这一路是如何进化的。

一、原始时代:wait/notify 的"信号枪"

想象有两个工人:工人A负责生产面包,工人B负责包装面包。工人A生产完面包后,要告诉工人B可以开始包装了;工人B包装完,也要通知工人A可以继续生产了。

在Java里,我们可以用wait/notify来实现这个过程。wait方法就像工人暂时放下手头工作去休息,notify方法就像吹响信号枪,唤醒正在休息的工人。

public class WaitNotifyExample {private static final Object lock = new Object();private static boolean hasProduct = false;public static void main(String[] args) {// 生产者线程new Thread(() -> {while (true) {synchronized (lock) {while (hasProduct) {try {lock.wait(); // 没有包装完,等待} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("生产了一个面包");hasProduct = true;lock.notify(); // 通知包装工人}}}).start();// 消费者线程new Thread(() -> {while (true) {synchronized (lock) {while (!hasProduct) {try {lock.wait(); // 没有面包,等待} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("包装了一个面包");hasProduct = false;lock.notify(); // 通知生产工人}}}).start();}
}

wait/notify有个很大的问题:notify只能随机唤醒一个等待的线程。如果有多个不同类型的线程在等待,很可能唤醒的不是我们想要的那个,这就像在操场上随便喊一嗓子,不知道谁会回应。

二、新时代:Condition 的"私人对讲机"

为了解决wait/notify的问题,Java引入了Condition接口,它就像给每个工人配备了一个私人对讲机。每个Condition对象都可以管理一组线程,我们可以精准地唤醒特定的线程。

Condition通常和Lock接口一起使用,代替传统的synchronized关键字。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ConditionExample {private static final Lock lock = new ReentrantLock();private static final Condition hasProductCondition = lock.newCondition();private static boolean hasProduct = false;public static void main(String[] args) {// 生产者线程new Thread(() -> {while (true) {lock.lock();try {while (hasProduct) {hasProductCondition.await(); // 没有包装完,等待}System.out.println("生产了一个面包");hasProduct = true;hasProductCondition.signal(); // 通知包装工人} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}).start();// 消费者线程new Thread(() -> {while (true) {lock.lock();try {while (!hasProduct) {hasProductCondition.await(); // 没有面包,等待}System.out.println("包装了一个面包");hasProduct = false;hasProductCondition.signal(); // 通知生产工人} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}).start();}
}

Conditionawait方法就像工人通过对讲机说"我先休息了",signal方法就像通过对讲机精准呼叫特定的工人。相比wait/notifyCondition提供了更灵活、更精准的线程通信方式。

三、总结:为什么要进化?

wait/notifyCondition,Java线程通信的进化主要解决了以下几个问题:

  1. 精准唤醒Condition可以精准唤醒特定的线程,避免无效唤醒
  2. 多个等待队列:一个Lock可以创建多个Condition,管理不同类型的线程
  3. 更灵活的操作Condition配合Lock使用,比synchronized更灵活

对于初学者来说,wait/notify简单直接,但功能有限;Condition虽然复杂一些,但在处理复杂多线程场景时更得心应手。随着学习的深入,大家会发现Condition的强大之处。

希望通过这篇文章,能让大家对Java线程通信的进化有一个清晰的认识。下次遇到多线程通信的问题,就知道该用哪个工具啦!

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

相关文章:

  • Unity3D Lua集成技术指南
  • kubesphere 单节点启动 etcd 报错
  • 3、LangChain基础:LangChain Chat Model
  • 从FP32到BF16,再到混合精度的全景解析
  • 高等数学第二章---导数与微分(2.1~2.3)
  • 多模态大语言模型arxiv论文略读(四十)
  • 语音合成之五语音合成中的“一对多”问题主流模型解决方案分析
  • Synopsys 逻辑综合的整体架构概览
  • vscode 打开csv乱码
  • 4.5/Q1,GBD数据库最新文章解读
  • Dubbo负载均衡策略深度解析
  • 洛谷 B3647:【模板】Floyd 算法
  • 筑牢数字防线:商城系统安全的多维守护策略
  • 《解锁LLMs from scratch:开启大语言模型的探索之旅》
  • Electron Forge【实战】阿里百炼大模型 —— AI 聊天
  • BGP网络协议
  • 数据可视化平台产品介绍及功能特色
  • .NET 10 中的新增功能
  • 力扣347:前K个高频元素
  • 文章记单词 | 第43篇(六级)
  • Kafka和flume整合
  • cJSON中#define cJSON_IsReference 256 和 #define cJSON_StringIsConst 512这定义的大小是?
  • CSS常见布局
  • 逐行解析性能奥秘:借助 `line_profiler` 深入优化热点函数
  • MySQL 从入门到精通:第二篇 - 数据类型、约束与索引
  • 【华为HCIP | 华为数通工程师】821—多选解析—第十六页
  • 那些年踩过的坑之Arrays.asList
  • CC攻击的类型都有哪些?
  • eclipse怎么导入junit4
  • 解读《数据资产质量评估实施规则》:企业数据资产认证落地的关键指南