Java多线程wait notify和park unpark的使用

news/2024/10/17 12:32:46/

目录

    • 一、wait & notify的使用
      • 1、API介绍
      • 2、demo
      • 2、多线程模式
      • 3、wait和notify的原理
    • 二、Park & Unpark的使用
      • 1、基本使用
      • 2、特点
      • 3、park和unpark的原理

一、wait & notify的使用

1、API介绍

obj.wait() 让进入 object 监视器的线程到 waitSet 等待
obj.wait(n) 让进入 object 监视器的线程到 waitSet 等待,n秒后还没有被唤醒的话,则自动醒来
obj.notify() 在 object 上正在 waitSet 等待的线程中挑一个唤醒
obj.notifyAll() 让 object 上正在 waitSet 等待的线程全部唤醒

它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法
wait() 方法会释放对象的锁,进入 WaitSet 等待区,从而让其他线程就机会获取对象的锁。无限制等待,直到notify 为止
wait(long n) 有时限的等待, 到 n 毫秒后结束等待,或是被 notify
notify 只能随机唤醒一个 WaitSet 中的线程,这时如果有其它线程也在等待,那么就可能唤醒不了正确的线程,称之为【虚假唤醒】

2、demo

@Slf4j(topic = "c.TestCorrectPosture")
public class TestCorrectPostureStep5 {static final Object room = new Object();static boolean hasCigarette = false;static boolean hasTakeout = false;public static void main(String[] args) {new Thread(() -> {synchronized (room) {log.debug("有烟没?[{}]", hasCigarette);while (!hasCigarette) {log.debug("没烟,先歇会!");try {room.wait();} catch (InterruptedException e) {e.printStackTrace();}}log.debug("有烟没?[{}]", hasCigarette);if (hasCigarette) {log.debug("可以开始干活了");} else {log.debug("没干成活...");}}}, "小南").start();new Thread(() -> {synchronized (room) {Thread thread = Thread.currentThread();log.debug("外卖送到没?[{}]", hasTakeout);while (!hasTakeout) {log.debug("没外卖,先歇会!");try {room.wait();} catch (InterruptedException e) {e.printStackTrace();}}log.debug("外卖送到没?[{}]", hasTakeout);if (hasTakeout) {log.debug("可以开始干活了");} else {log.debug("没干成活...");}}}, "小女").start();sleep(1);new Thread(() -> {synchronized (room) {hasTakeout = true;log.debug("外卖到了噢!");room.notifyAll();}}, "送外卖的").start();}
}

在这里插入图片描述

2、多线程模式

模式之保护性暂停
模式之生产者消费者

3、wait和notify的原理

二、Park & Unpark的使用

1、基本使用

它们是 LockSupport 类中的方法

// 暂停当前线程
LockSupport.park(); 
// 恢复某个线程的运行
LockSupport.unpark(暂停线程对象)

先 park 再 unpark

public static void main(String[] args) {Thread t1 = new Thread(() -> {log.debug("start...");sleep(1);log.debug("park...");LockSupport.park();log.debug("resume...");}, "t1");t1.start();sleep(4);log.debug("unpark...");LockSupport.unpark(t1);}

在这里插入图片描述
先 unpark 再 park

public static void main(String[] args) {Thread t1 = new Thread(() -> {log.debug("start...");sleep(2);log.debug("park...");LockSupport.park();log.debug("resume...");}, "t1");t1.start();sleep(1);log.debug("unpark...");LockSupport.unpark(t1);}

在这里插入图片描述
结论:park和unpark是成对出现,但是是不分先后的

2、特点

与 Object 的 wait & notify 相比

  • wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必
  • park & unpark 是以线程为单位来【阻塞】和【唤醒】线程(唤醒的时候可以传一个线程作为参数),而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么【精确】
  • park & unpark 可以先 unpark,而 wait & notify 不能先 notify

3、park和unpark的原理


http://www.ppmy.cn/news/239661.html

相关文章

安装银河麒麟操作系统

文章目录 一、安装银河麒麟操作系统1.1、简介1.2、银河麒麟高级服务器操作系统V101.3、下载银河麒麟镜像1.4、安装银河麒麟操作系统兼容版 一、安装银河麒麟操作系统 1.1、简介 银河麒麟(KylinOS)原是在863计划和国家核高基科技重大专项支持下&#xf…

java中通过split方法使用分号分割,使用正则表达式匹配不识别单引号中的分号

在Java中&#xff0c;使用split()方法可以通过指定正则表达式作为分隔符来拆分字符串。如果你想忽略单引号内的分号&#xff0c;可以使用以下代码&#xff1a; String str "aaa;bbb;ccc;ddd;eee"; String[] arr str.split("(?<!\\\\);(?(([^\]*\[^\]*\)…

mysql慢sql优化实战:in order by优化处理

背景 线上查询慢的问题日益突出,专门写一个帖子记录一下处理过程,会定期更新优化处理方案 套餐余量统计查询菜单,数据库查询时间一分钟五十秒,优化之后耗时109毫秒,性能提升很大.所有时间统计均以数据库层面进行统计.用户使用层面因为有数据传输、带宽、业务逻辑处理等因素…

Stable Diffusion原理说明

本文参考&#xff1a;深入浅出讲解Stable Diffusion原理&#xff0c;新手也能看明白 - 知乎 目录 1、Stable Diffusion能做什么&#xff1f; 2、扩散模型&#xff08;Diffusion model&#xff09; &#xff08;1&#xff09;前向扩散&#xff08;Forward Diffusion&#xff…

佳能相机G7 Mark Ⅱ (曝光补偿)

曝光指示表&#xff08;判断正常&#xff09; M模式下 曝光补偿表 P / TV / AV 何时用曝光补偿 口诀 白加&#xff08;逆光人脸&#xff09; 黑减&#xff08;剪影5&#xff09; 一般来说-1的曝光补偿已经非常能够左右画面的明暗了

佳能相机G7 Mark Ⅱ (曝光模式)

AUTO 全自动&#xff0c;什么都不需要调 P &#xff08;初级学习&#xff09; 相机只配对光圈&#xff0c;快门 自己可以调节的是&#xff1a;ISO , 曝光补偿 &#xff0c; 测光模式 TV&#xff08;中级学习&#xff09; 快门优先模式&#xff0c;自己调节一个快门值&#xf…

Jetson 相机编码

Jetson 相机编码 Jetson相机编码是即将发布的“实践”系列的相关代码。有三个存储库: 1. camera-caps JetsonHacks Github存储库camera-caps 通过v4l2-ctl命令行工具提供了一个图形用户界面。您可能会发现&#xff0c;它可以方便地检查连接到Jetson上的V4L2相机的功能。这适…

MySQL(进阶篇2.0)

SQL优化 插入数据 insert 如果需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化 1、优化方案一 批量插入数据 insert into tb_test values(1, Tom),(2,Cat),(3,Jerry);2、优化方案二 手动控制事务 start transaction; insert into tb_test v…