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

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 多线程程序的性能和可靠性。

相关文章:

Java锁等待唤醒机制

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

Docker Compose 常用命令详解

Docker Compose 常用命令详解 Docker Compose 是 Docker 官方提供的一个用于管理多个容器的工具,可以使用 docker-compose.yml 文件定义和运行多容器应用。本篇博客将详细介绍 Docker Compose 的常用命令,帮助你更高效地管理容器。 1. docker compose u…...

C站算法技能题-题解(javascript)

切面条 const 切面条 (n10)>{return 2 ** n 1; } 切面条(0) 2 切面条(1) 3 切面条(2) 5 切面条(10) 1025大衍数列 const 大衍数列 (n100) > {let ans []for(let i1;i<n;i){if(i%2 0){ans.push((i ** 2 ) / 2)}else{ans.push((i ** 2 - 1) / 2)}}return ans…...

【Docker系列一】Docker 简介

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

C++进阶——封装红黑树实现map和set

目录 1、源码及框架分析 2、模拟实现map和set 2.1 复用的红黑树框架及Insert 2.2 iterator的实现 2.2.1 iterator的核心源码 2.2.2 iterator的实现思路 2.3 map支持[ ] 2.4 map和set的代码实现 2.4.1 MyMap.h 2.4.2 MySet.h 2.4.3 RBTree.h 2.4.4 Test.cpp 1、源码及…...

python基础-02-列表+序列数据类型

文章目录 【README】【4】python列表【4.1】列表数据类型【4.1.1】用索引取得列表中的单个值【4.1.2】负数索引【4.1.3】利用切片获取子列表【4.1.4】用索引改变列表中的值【4.1.5】列表连接与复制【4.1.6】del语句删除列表中的元素 【4.2】使用列表【4.2.1】列表用于循环【补充…...

‘闭包‘, ‘装饰器‘及其应用场景

‘闭包’, 装饰器’及其应用场景 一, 闭包及其应用场景 图解 闭包的定义 概述: 内部函数 使用了 外部函数 的变量, 这种写法就称之为闭包. 格式: def 外部函数名(形参列表):外部函数的(局部)变量def 内部函数名(形参列表):内部函数的(局部)变量return 内部函数名前提条件: …...

IDEA 快捷键ctrl+shift+f 无法全局搜索内容的问题及解决办法

本篇文章主要讲解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列编辑器无法进行全局搜索内容问题的主要原因及解决办法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聪聪 现象描述&#xff1a; 1.按下ctrlshiftf 输入法转为了繁体。 2.快捷键ctrlshiftr 可以全局检…...

Java——Random库

一、作用 Random库——生成随机数 二、实现步骤 1.导包&#xff1a;import java.util.Random; #快捷键&#xff1a;“Random”回车键 2.取得随机数&#xff1a;Random 变量1 new Random(); 3.调用随机数&#xff1a;类型 变量2 变量1.nextInt(n); &#xff08;代表变量…...

【通过Groovy去热修复线上逻辑】1.执行线上数据修复 2.写工具

1.执行groovy // 实际执行的话, 我们是通过vue提交的 http://localhost:8080/groovy/execute?scriptimport com.example.groovytest.controller.LoginController; LoginController.num251222 还有个技巧: 而执行执行的&#xff0c;则是: 写的工具什么的&#xff0c;想直接使…...

Powershell WSL导出导入ubuntu22.04.5子系统

导出Linux子系统 导出位置在C盘下,根据自己的实际情况更改即可Write-Host "export ubuntu22.04.5" -ForegroundColor Green wsl --export Ubuntu-22.04 c:\Ubuntu-22.04.tar 导入Linux子系统 好处是目录可用在任意磁盘路径,便于迁移不同的设备之间Write-Host &quo…...

【005安卓开发方案调研】之Flutter+Dart技术开发安卓

基于2025年国内移动开发环境现状&#xff0c;结合多份行业分析报告和技术文档&#xff0c;对FlutterDart开发安卓应用的技术成熟度和生态适配性分析如下&#xff1a; 一、技术成熟度评估 1. 跨平台能力达到生产级标准 Flutter的Skia自渲染引擎和Dart的AOT/JIT双编译模式&…...

论文笔记(七十三)Gemini Robotics: Bringing AI into the Physical World

Gemini Robotics: Bringing AI into the Physical World 文章概括1. 引言2. Gemini 2.0的具身推理2.1. 具身推理问答&#xff08;ERQA&#xff09;基准测试2.2. Gemini 2.0的具身推理能力2.3. Gemini 2.0支持零样本和少样本机器人控制 3. 使用 Gemini Robotics 执行机器人动作3…...

AI + 医疗 Qwq大模型离线本地应用

通义千问Qwq-32b-FP16可用于社区医院、乡镇卫生院、诊所等小型医疗机构&#xff0c;替代专业合理用药系统&#xff0c;作为药品知识库&#xff0c;实现以下功能&#xff1a; 药品信息智能查询&#xff1a;检索药品的详细说明书、适应症、禁忌症、不良反应及药物相互作用等关键信…...

Vue 3 项目实现国际化指南 i18n

引言 在开发现代 Web 应用时&#xff0c;国际化&#xff08;Internationalization&#xff0c;简称 i18n&#xff09;已经成为一个不可或缺的功能。无论是面向全球用户的商业网站&#xff0c;还是需要支持多语言的企业应用&#xff0c;良好的国际化支持都能显著提升用户体验。本…...

元音辅音及其字母组合发音

文章目录 单元音长元音/ɑː//ɔ://u://i://ɜː/// 短元音/ʌ//ɒ//ʊ//ɪ//ə//e/ 双元音/eɪ//aɪ//ɔɪ//ɪə//eə//ʊə//əʊ//aʊ/ 辅音3个鼻辅音m n ŋ 5个独立浊辅音w j r l h 20个清浊相对的辅音s zʃ ʒf vθ p bt dk gts dztʃ dʒtr dr 以下是列举的部分字母组合…...

【Vitis AIE】FPGA图像处理 11 双线性插值 Bilinear Interpolation

双线性插值 https://github.com/Xilinx/Vitis-Tutorials/tree/2024.2/AI_Engine_Development/AIE/Design_Tutorials/11-Bilinear_Interpolation 简介 双线性插值是一种使用重复线性插值来插值两个变量函数的方法。它通常用于以下应用&#xff1a; 图像处理和计算机视觉&…...

Linux | 安装 Samba将ubuntu 的存储空间指定为windows 上的一个磁盘

01 安装 samba 文件来实现。比如把我们 ubuntu 的存储空间指定为我们 windows 上的一个磁盘,然后我们在这个磁盘里面创建 .c 文件,进行我们代码的修改和编写,可以安装 samba 文件来实现。 samba 是一种网络共享服务,可以通过网络访问我们指定的文件夹 02 第一步:下…...

一文说清预训练与微调:AI的双重训练法则

什么是预训练&#xff1f; 预训练是大型语言模型训练的第一步。它在资金和计算能力的支持下&#xff0c;通过深入分析大量的文本数据&#xff0c;使模型建立起语言的基本构架。在这一阶段&#xff0c;模型通过学习海量的书籍、文章和网页&#xff0c;识别出语言的语法、句法和…...

solana增加流动性和删除流动性

在 Solana 区块链上增加和删除流动性通常通过去中心化交易所&#xff08;DEX&#xff09;实现&#xff0c;例如 Raydium 或 Orca。以下是详细的操作流程和注意事项&#xff1a; 一、增加流动性 步骤&#xff1a; 1. 连接钱包 使用支持 Solana 的钱包&#xff08;如 Phantom、…...

996引擎-接口测试:音效测试NPC

996引擎-接口测试:音效测试NPC 参考资料local offset = 1 -- 默认偏移量function main(player, newOffset)offset = newOffset or offset -- 更新偏移量local buttonWidth =...

javabean类,测试类,工具类都是什么?

JavaBean类 用来描述一类事物的类。比如Student、Teacher、Dog、Cat 例如下面的这个就是JavaBean类 package com.hong.static01demo;public class Student {//姓名&#xff0c;年龄&#xff0c;性别private String name;private int age;private String gender;public stati…...

基于C8051F020单片机的液晶显示,LCD1602并口驱动,单片机并口驱动LCD1602

一、前言 LCD1602是一种广泛使用的字符型液晶显示模块&#xff0c;有8根数据线和3根控制线E&#xff0c;RS和R/W&#xff0c;8根数据线与单片机P6连接&#xff0c;3根控制线与使用P1口的P1.4、P1.5、P1.6连接&#xff0c;VO连接了P1.7&#xff0c;通过给P1.7赋值0或1&#xff…...

miniconda安装保姆级教程|win11|深度学习环境配置

一、官网安装miniconda miniconda官网&#xff1a;Miniconda - Anaconda 点击Download按钮 在红框位置输入邮箱并点击submit&#xff0c;下载链接将会发到邮箱中 邮箱中将会收到如图所示邮件&#xff0c;点击下载 选择windows对应的miniconda安装包 miniconda安装包安装完成如…...

算力100问☞第92问:为什么各地热衷建设算力中心?

目录 1、宏观分析 2、政府角度分析 3、投资者角度分析 在数字化浪潮中,各地对算力中心建设的热情高涨,这一现象背后潜藏着诸多深层次的原因,涵盖了经济、科技、社会等多个维度,且彼此交织,共同驱动着这一发展趋势。 1、宏观分析 从经济结构转型的底层逻辑来看,全球经…...

HTML字符实体笔记

一、概述 在HTML中&#xff0c;某些字符具有特殊含义&#xff0c;不能直接用于网页内容显示&#xff0c;需要使用字符实体来代替。字符实体分为两类&#xff1a;字符实体名称和字符实体编号。字符实体名称由&开头&#xff0c;后跟实体名称&#xff0c;以分号;结束&#xf…...

Linux shell脚本-概述、语法定义、自定义变量、环境变量、预设变量、变量的特殊用法(转义字符、单双引号、大小括号)的验证

目录 1.shell概述 1.1作为应用程序&#xff1a; 1.2 shell 作为一门语言 2.shell 语法 2.1 shell脚本的定义与执行 &#xff08;1&#xff09;新建文件 &#xff08;2&#xff09;程序开头第一行 必须写shell的类型 &#xff08;3&#xff09;程序编写完后&#xff0c…...

数据驱动进化:AI Agent如何重构手机交互范式?

如果说AIGC拉开了内容生成的序幕&#xff0c;那么AI Agent则标志着AI从“工具”向“助手”的跨越式进化。它不再是简单的问答机器&#xff0c;而是一个能够感知环境、规划任务并自主执行的智能体&#xff0c;更像是虚拟世界中的“全能员工”。 正如行业所热议的&#xff1a;“大…...

DL学习笔记:穿戴设备上的轻量级人体活动识别方法

Hello&#xff0c;大家好&#xff01;这里是《Dream 的深度学习笔记》,本系列将聚焦三个学习方面&#xff1a; 论文解读&#xff1a;拆解经典论文与最新突破 技术实现&#xff1a;从模型搭建到实际部署 应用案例&#xff1a;涵盖图像识别、深度学习、人工智能等热门方向 让…...

拓展知识三:编码学及密码学

编码和密码的区别 研究密码变化的客观规律&#xff0c;应用于编制密码以保守通信秘密的&#xff0c;称为编码学&#xff1b;应用于破译密码以获取通信情报的&#xff0c;称为破译学&#xff0c;总称密码学。 编码和密码是两个不同的概念&#xff0c;它们的区别如下&#xff1a;…...