码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 5.玩明白wait-notify-notifyAll方法


    今天总结一下wait-notify-notifyAll 方法,到底该怎么玩。

    1.wait、 notify、 notifyAll

    在使用 wait 方法时,必须把 wait 方法写在 synchronized 保护的 while 代码块中,并始终判断执行条件是否满足,如果满足就往下继续执行,如果不满足就执行 wait 方法,而在执行 wait 方法之前,必须先持有对象的 monitor 锁,也就是通常所说的 synchronized 锁。

    为什么这么玩呢?

    如果不要求 wait 方法放在 synchronized 保护的同步代码中使用,而是可以随意调用,会发生什么呢?

    首先会造成线程不安全的情况。这个网站上有很多案例 可以自己去搜索。

    所以我们在写代码的时候要这样写:

    这样就可以确保 notify 方法永远不会在 buffer.isEmpty 和 wait 方法之间被调用,提升了程序的安全性。

    //被 synchronized 保护的同步代码
    public void notifyTest(String data) {
       synchronized (this) {
          buffer.add(data);
          notify();
      }
    }
    //被 synchronized 保护的同步代码
    public String waitTest() throws InterruptedException {
       synchronized (this) {
        while (buffer.isEmpty()) {
             wait();
           }
         return buffer.remove();
      }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    小知识【虚假唤醒】:

    “虚假唤醒”(spurious wakeup)的问题,线程可能在既没有被notify/notifyAll,也没有被中断或者超时的情况下被唤醒。
    虽然在实际生产中,虚假唤醒发生的概率很小,但是程序依然需要保证在发生虚假唤醒的时候的正确性,所以就需要采用while循环的结构。
    这样即便被虚假唤醒了,也会再次检查while里面的条件,如果不满足条件,就会继续wait,也就消除了虚假唤醒的风险。

    2.wait/notify 和 sleep 方法的区别

    相同点:

    • 它们都可以让线程阻塞。
    • 它们都可以响应 interrupt 中断:在等待的过程中如果收到中断信号,都可以进行响应,并抛出 InterruptedException 异常。

    不同点:

    • wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求。
    • 在同步代码中执行 sleep 方法时,并不会释放 monitor 锁,但执行 wait 方法时会主动释放 monitor 锁。
    • sleep 方法中会要求必须定义一个时间,时间到期后会主动恢复,而对于没有参数的 wait 方法而言,意味着永久等待,直到被中断或被唤醒才能恢复,它并不会主动恢复。
    • wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法。
  • 相关阅读:
    C++ 将off格式文件转换成ply格式存储
    HTML非遗文化网页设计题材【京剧文化】HTML+CSS(大美中国 14页 带bootstarp)
    springboot进行微信公众号相关开发:(一)编写接口激活配置信息用,用以实现公众号与配置信息接口的绑定
    go操作mysql
    GAN论文精读 P2GAN: Posterior Promoted GAN 用鉴别器产生的后验分布来提升生成器
    设计模式(结构型设计模式——桥接模式)
    java毕业生设计二手车交易市场网站计算机源码+系统+mysql+调试部署+lw
    arm 内核版本编译记录
    阿里云服务器基础linux指令实验(一到五)
    配置mysql+Navicat+XShell宝塔:Mark
  • 原文地址:https://blog.csdn.net/daohangtaiqian/article/details/128014940
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号