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

【JavaEE】多线程 -- 线程等待wait和notify

目录

  • 线程等待的目的
  • wait方法
    • wait的使用
  • notify方法
  • notifyall方法
  • wait和sleep的区别(重点)

线程等待的目的

  • 在多线程的程序中, 我们线程通常需要等待某个线程来配合执行完成任务. 比如生活中我们打篮球, 要先传球给投篮的那个队友, 队友才能有机会把篮球投进去. 在传给他求之前, 负责投篮的那个队友一直在等待其他队友给他传球. 线程之间也是这样
  • 这里我们就可以用这4个方法来决定线程执行顺序的目的

在这里插入图片描述

  • 以上方法都属于 Object 类的方法,只要是类对象(不包含基本数据类型)都可以使用。

wait方法

  • 有人说线程等待不是前面说过了吗, join就可以了.
  • join 也算是一种控制线程顺序的方式, 但是本质上的区别在于,join 是一个线程等待另一个线程执行完毕后再继续执行,wait() 就是让线程停下来等一等,另一个线程调用notify(并且执行完锁里面的代码) 就可以把该线程唤醒就能够继续执行,多线程之间针对某一个代码块的执行顺序就很灵活
  • wait方法做的事情

1.释放当前的锁
2.等待其他线程的通知(当前线程进入阻塞状态)
3.当通知到达后, 从阻塞状态回到就绪状态, 并且重新获取到锁.

  • 这里我们要保证第一步和第二步是原子的, 也就是要合并在一起执行.如果不是原子的, 那么问题就大了. t1线程错过会t2线程的通知, 那么就无人唤醒t1线程了.
    在这里插入图片描述

我们在使用 wait() 方法的大前提是必须在 synchaonized(加锁) 的状态下(因为我们wait方法要做的第一件事情解释解锁),如果在没有加锁的代码块中使用 wait() 方法就会抛出 “IllegalMonitorStateException”异常。

在这里插入图片描述

  • 注意wait方法解锁后, 并不会对后面的代码造成线程不安全的问题,
    在这里插入图片描述
  • wait() 结束等待的条件:
  1. 其他线程调⽤该对象的 notify ⽅法.
  2. wait 等待时间超时 (wait ⽅法提供⼀个带有 timeout 参数的版本, 来指定等待时间).
  3. 其他线程调用该等待线程的 interrupted() 方法(判断线程是否设置了中断标志位,这是Thread 中断线程的一个机制),导致抛出InterruptedException 异常

wait的使用

public class demo19 {public static void main(String[] args) {Object locker = new Object();Thread t1 = new Thread(()->{synchronized (locker){System.out.println("t1 wait之前");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t1 wati之后");}});t1.start();}
}

在这里插入图片描述

  • 可以看到我们的t1线程就一直阻塞在这里, 等待其他线程把他唤醒.
  • 当然我们在实际场景中, 我们也有不能一直等待的情况. 所以我们的wati还有两个版本
    在这里插入图片描述

notify方法

  • notify() 方法的作用就是用来唤醒等待的线程的。
  1. 该方法是在(锁住的代码同步)同步方法和同步块中使用, 用于通知那些可能等待该对象锁的其他线程, 唤醒这个线程, 并且释放对象锁让这个线程拿到.
  2. 如果有多个线程等待,则有线程调度器随机挑选出⼀个呈 wait 状态的线程。(并没有 “先来后到”)
  3. 在使用完notify方法之后, 这个线程并不会立即释放对象锁, 直到这个线程执行完(到达}), 才会释放这个对象锁. 这也意味着, 我们等待对象锁的线程被唤醒后, 并不能马上拿到对象锁. 必须等占有对象锁的线程把代码执行完, 才能拿到这把锁.

在这里插入图片描述
在这里插入图片描述

notifyall方法

  • notify⽅法只是唤醒某⼀个等待线程. 使⽤notifyAll⽅法可以⼀次唤醒所有的等待线程.

notify 只唤醒等待队列中的⼀个线程. 其他线程还是乖乖等着
notifyAll ⼀下全都唤醒, 需要这些线程重新竞争锁

在这里插入图片描述

wait和sleep的区别(重点)

在这里插入图片描述

  • wait设定超时时间是后手, 主要是通信中, 等待其他线程唤醒.

在这里插入图片描述

http://www.dtcms.com/a/334583.html

相关文章:

  • 对话访谈|盘古信息×智晟威:深度挖掘数字化转型的奥秘
  • 【数据结构】深入理解单链表与通讯录项目实现
  • git revert
  • Java Condition 对象 wait 方法使用与修复方案
  • 云计算-Kubernetes+Istio 实现金丝雀发布:流量管理、熔断、流量镜像、ingreess、污点及pv案例实战
  • 如何防止 RabbitMQ 的消息丢失?如何保证消息的可靠传输?
  • Python 项目高频设计模式实战指南:从理念到落地的全景剖析
  • Linux软件编程--线程
  • 蓝牙音频ANC四通道测试解决方案
  • 新经济形态下人才能力结构变革与发展研究报告
  • Win10快速安装.NET3.5
  • RecSys:多目标模型和MMOE
  • .NET8下的Garnet使用
  • androidstudio内存大小配置
  • 研究生第十六周周报
  • 718SJBH公交查询系统
  • 4.6 Vue 3 中的模板引用 (Template Refs)
  • Sklearn 机器学习 邮件文本分类 加载邮件数据
  • [Responsive theme color] 动态主题 | 色彩工具函数 | HEX与RGB
  • 嵌入式第三十天(线程)
  • 围棋对战游戏开发详解 附源码
  • 【C++】标准库中用于组合多个值的数据结构pair、tuple、array...
  • k8s+kubeedge的混合框架下,云端pod与边缘端pod如何进行通信?
  • HTTP协议-1-认识各个HTTP协议版本的主要特点
  • Python进行点云公共区域的提取
  • Docker目录的迁移
  • 银行间交易IMIX协议加密相关
  • 后台管理系统-4-vue3之pinia实现导航栏按钮控制左侧菜单栏的伸缩
  • 机器学习——线性回归
  • 平滑方法(smoothing)