Java锁等待唤醒机制

在 Java 并发编程中,锁的等待和唤醒机制至关重要,通常使用 wait()notify()notifyAll() 来实现线程间的协调。本文将详细介绍这些方法的用法,并通过示例代码加以说明。

1. wait()notify()notifyAll()

在 Java 中,Object 类提供了 wait()notify()notifyAll() 方法,它们用于线程间的通信。

  • wait():使当前线程进入等待状态,并释放锁。
  • notify():唤醒单个等待线程。
  • notifyAll():唤醒所有等待线程。

注意,这些方法必须在同步代码块(synchronized)中调用,否则会抛出 IllegalMonitorStateException

2. 示例代码

下面的示例展示了 wait()notify() 的使用。

class SharedResource {private boolean available = false;public synchronized void produce() {while (available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}System.out.println("Producing an item");available = true;notify();}public synchronized void consume() {while (!available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}System.out.println("Consuming an item");available = false;notify();}
}public class WaitNotifyExample {public static void main(String[] args) {SharedResource resource = new SharedResource();Thread producer = new Thread(resource::produce);Thread consumer = new Thread(resource::consume);producer.start();consumer.start();}
}

3. wait()notify() 的工作原理

  1. 生产者线程 produce()availabletrue 时调用 wait() 进入等待状态,释放锁。
  2. 消费者线程 consume()availablefalse 时调用 wait() 进入等待状态,释放锁。
  3. produce() 生产后调用 notify() 唤醒 consume()
  4. consume() 消费后调用 notify() 唤醒 produce()

4. notifyAll() 的使用场景

notify() 仅唤醒一个线程,而 notifyAll() 可用于有多个等待线程的情况,以防止某些线程被永久阻塞。

public synchronized void produce() {while (available) {try {wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}System.out.println("Producing an item");available = true;notifyAll();
}

5. LockCondition 方式

除了 synchronized,还可以使用 LockCondition 进行等待和唤醒控制。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class SharedResourceWithLock {private boolean available = false;private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();public void produce() {lock.lock();try {while (available) {condition.await();}System.out.println("Producing an item");available = true;condition.signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}public void consume() {lock.lock();try {while (!available) {condition.await();}System.out.println("Consuming an item");available = false;condition.signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}
}

6. 总结

  • wait()notify() 需要在 synchronized 块中使用。
  • notifyAll() 可防止线程被永久阻塞。
  • LockCondition 提供更灵活的等待和唤醒机制。

合理使用这些机制可以提升 Java 多线程程序的性能和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

 UNIX网络编程笔记:TCP客户/服务器程序示例

服务器实例 有个著名的项目&#xff0c;tiny web&#xff0c;本项目将其改到windows下&#xff0c;并使用RAII重构&#xff0c;编写过程中对于内存泄漏确实很头疼&#xff0c;还没写完&#xff0c;后面会继续更&#xff1a; #include <iostream> #include <vector&g…

AI Agent开发大全第四课-提示语工程:从简单命令到AI对话的“魔法”公式

什么是提示语工程&#xff1f;一个让AI“听话”的秘密 如果你曾经尝试过用ChatGPT或者其他大语言模型完成任务&#xff0c;那么你一定遇到过这样的情况&#xff1a;明明你的问题是清晰的&#xff0c;但答案却离题万里&#xff1b;或者你认为自己提供的信息足够详尽&#xff0c…

系统架构设计知识体系总结

1.技术选型 1.什么是技术选型&#xff1f; 技术选型是指评估和选择在项目或系统开发中使用的最合适的技术和工具的过程。这涉及考虑基于其能力、特性、与项目需求的兼容性、可扩展性、性能、维护和其他因素的各种可用选项。技术选型的目标是确定与项目目标相符合、能够有效解…

基于3DMax与Vray引擎的轻量级室内场景渲染实践

欢迎踏入3DMAX室内渲染的沉浸式学习之旅!在这个精心设计的实战教程中,我们将携手揭开3DMAX与Vray这对黄金搭档在打造现实室内场景时的核心奥秘。无论您是渴望入门的3D新手,还是追求极致效果的专业设计师,这里都将为您呈现从场景蓝图构建到光影魔法施加的完整技术图谱。我们…

逻辑卷,vdo,(阿里加速器)

一、逻辑卷 10 20 30 1.逻辑卷的2个特点 &#xff08;1&#xff09;逻辑卷可以将多个分区或者磁盘整合成一个更大的逻辑磁盘&#xff0c;然后可以从逻辑磁盘上划分出分区&#xff08;逻辑磁盘的大小等于整合的物理磁盘大小之和。&#xff09; &#xff08;2&#xff09;能…

检索增强生成(2)本地PDF 本地嵌入模型

from langchain_community.document_loaders import PyPDFLoader from pathlib import Pathdef load_local_pdf(file_path):if not Path(file_path).exists():raise FileNotFoundError(f"文件 {file_path} 不存在&#xff01;")loader PyPDFLoader(file_path)try:do…

安全守护:反光衣检测技术的革新之路

视觉分析助力船上工人反光衣检测 在现代工业生产与作业环境中&#xff0c;安全始终是首要考虑的因素。对于水上作业&#xff0c;如船舶维护、海上施工等场景&#xff0c;工人穿戴反光衣是预防事故、提高可见性的重要措施。然而&#xff0c;传统的人工检查方式不仅效率低下&…

【Scrapy】Scrapy教程8——处理子链接

通过前面几篇文章,已经了解了如何去爬取网页内容并存储到数据库,但是目前只是存储了一个页面的内容,现在想要获取每篇文章链接内的文章内容,我们来看看怎么获取。 生成新请求 首先我们肯定要先拿到链接,所以第一步都获取文章标题和链接肯定少不了,然后再爬取获取到到子…

Centos6配置yum源

Centos6配置yum源 为Centos6配置CentOS Vault源—防止yum源过期为Centos6配置epel源为Centos6配置ELRepo源---已ELRepo被官方清空Centos6安装dockerdocker配置国内镜像加速 为Centos6配置CentOS Vault源—防止yum源过期 参考&#xff1a;https://mirrors.ustc.edu.cn/help/cen…

“智改数转”新风口,物联网如何重构制造业竞争力?

一、政策背景 为深化制造业智能化改造、数字化转型、网络化联接&#xff0c;江苏省制定了《江苏省深化制造业智能化改造数字化转型网络化联接三年行动计划&#xff08;2025&#xff0d;2027年&#xff09;》&#xff0c;提出到2027年&#xff0c;全省制造业企业设备更新、工艺…

制作Oracle11g Docker 镜像

基于Linux系统&#xff0c;宿主主机要设置如下环境变量&#xff0c;oracle为64位版本 dockerfile中需要的数据库安装包可从csdn下载内找到 #!/bin/bash # 在宿主机上运行以设置Oracle所需的内核参数 # 这些命令需要root权限cat > /etc/sysctl.d/99-oracle.conf << EO…

从GTC2025首次量子日看英伟达量子AI融合算力网络前景与趋势

GTC2025 Quantum Day 最新内容全部汇总: 技术名称描述合作伙伴/开发者应用场景/目标量子模拟器优化方案NVIDIA与IonQ、D-Wave合作,针对量子模拟器进行性能优化,提升量子计算任务效率。IonQ、D-Wave量子算法开发、复杂系统模拟混合量子-经典计算架构结合量子计算与经典GPU加速…

UE4学习笔记 FPS游戏制作12 添加第二把枪,制作枪的父类,动态生成物体,切换武器

我们添加一个发射器类型的枪 我们目前有了一个Rifle的枪械蓝图&#xff0c;我们在添加Launcher时&#xff0c;需要为他们添加一个父类&#xff0c;将公共方法放到父类里&#xff0c;方法体由子类实现 添加父类 方法1 新建一个Gun的蓝图&#xff0c;Gun继承Actor&#xff0c;…

【原创首发】开源基于AT32 SIP/VOIP电话

前言 本次为了反馈各位粉丝的关注&#xff0c;特此分享 AT32_VOIP 工程&#xff0c;此功能其实跟我之前发过的《STM32F429的VOIP功能》是一样的&#xff0c;只是用了AT32F437。 其实那个工程是一个比较Demo中的Demo&#xff0c;很多功能和硬件依赖性太大了。后面项目中发现AT…

通俗易懂搞懂@RequestParam 和 @RequestBody

&#x1f4cc; 博主简介: &#x1f4bb; 努力学习的 23 级科班生一枚 &#x1f680;&#x1f3e0; 博主主页 &#xff1a; &#x1f4ce; 灰阳阳&#x1f4da; 往期回顾 &#xff1a;Session和Cookie我不允许你不懂&#x1f4ac; 每日一言&#xff1a; 「流水不争先&#xff0c…

dubbo版本与分组

Dubbo服务中&#xff0c;接口并不能唯一确定一个服务&#xff0c;只有 接口分组版本号 的三元组才能唯一确定一个服务。 当同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景&#xff0c;可使用服务分组来区分不同的实现方式。同时&#xff0c;这些不同实…

RAG现有技术方案

RAG现有技术方案 一、现有技术方案的核心问题 检索质量不足 挑战:传统RAG系统依赖单轮检索,难以应对智能电网的海量异构数据(如传感器读数、控制参数),导致检索结果相关性低、覆盖不全。案例:BM25稀疏检索在处理长文本或专业术语时,易遗漏语义关联;BGE等稠密检索模型对…

redis MISCONF Redis is configured to save RDB snapshots报错解决

直接上解决方案 修改redis配置文件 stop-writes-on-bgsave-error no 重启redis

个人学习编程(3-22) leetcode刷题

连续子数组&#xff1a;&#xff08;难&#xff09; 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。 示例 2: 输入: nums [0,1,0] 输出: 2 说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。 需要理解的知识&a…

希尔排序

希尔排序是一种改进的插入排序算法&#xff0c;它通过将原始数据分成多个子序列来改善插入排序的性能&#xff0c;每个子序列的元素间隔为 d&#xff08;增量&#xff09;。随着算法的进行&#xff0c;d 逐渐减小&#xff0c;最终减为 1&#xff0c;此时整个序列就被排序好了。…