虚假唤醒  Spurious wakeup

如果等待线程在没有通知被调用的情况下唤醒,则称为Spurious wakeup

解决方案就是:

使用while条件判断,更好的方案是避免使用wait这种低级的API,而是使用高级的并发工具。

因为这些高级的并发工具都是经过无数的坑才提炼出来的,如果你对底层缺乏深入的了解比如不知道虚假唤醒那么你没有做这种处理,你的代码可能会出问题。

synchronized(obj){ while(<condition not hold>)obj.wait(); ... //执行适合条件的操作}
}

这是使用wait()方法的标准习惯用法。在上面的场景中,如果任何其他线程发送了notify(),那么条件将不会成立并且将跳过wait()。考虑在此线程调用wait()之前是否没有while循环和其他一些线程调用通知,然后可能会发生它可能永远等待或直到调用下一个notify。

JDK 5中的等待方法的javadoc也已更新

线程也可以在没有被通知,中断或超时的情况下唤醒,即所谓的虚假唤醒。虽然这在实践中很少发生,但应用程序必须通过测试应该导致线程被唤醒的条件来防范它,并且如果条件不满足则继续等待。换句话说,等待应始终在循环中进行

Src:有效的Java作者:Joshua Bloch https://tech-read.com/2010/01/28/spurious-wakeup-in-java/

https://en.m.wikipedia.org/wiki/Spurious_wakeup

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html

==================================

看看其他人对Doug Lea关于虚假唤醒的评论:

https://coderanch.com/t/234023/java/spurious-wakeup

虚假的唤醒是真实的!

=============

http://opensourceforgeeks.blogspot.com/2014/08/spurious-wakeups-in-java-and-how-to.html

==============

https://stackoverflow.com/questions/2763714/why-do-pthreads-condition-variable-functions-require-a-mutex

=====================

对条件变量(condition variable)的讨论

=================================

问题代码分析:

https://www.linuxidc.com/Linux/2014-03/98715.htm

如何修复问题?

#1.  使用可同步的数据结构来存放数据,比如LinkedBlockingQueue之类。由这些同步的数据结构来完成繁琐的同步操作。

#2.  双层的synchronized使用没有意义,保留外层即可。

#3.  将if替换为while,解决虚假唤醒的问题。

多线程并发编程需要注意虚假唤醒Spurious wakeup相关推荐

  1. [C++11 多线程同步] --- 条件变量的那些坑【条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)】

    1 条件变量的信号丢失 1.1 条件变量的信号丢失场景重现 拿生产者和消费者模型举例,看一段示例代码: #include <iostream> #include <vector> ...

  2. Java 多线程 并发编程

    转载自  Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...

  3. Java多线程并发编程

    一.线程池 1.1.什么是线程池 线程池是一种多线程的处理方式,利用已有线程对象继续服务新的任务(按照一定的执行策略),而不是频繁地创建销毁线程对象,由此提高服务的吞吐能力,减少CPU的闲置时间.具体 ...

  4. Java多线程并发编程--Java并发包(JUC)

    Java多线程并发–Java并发包(JUC) 前言 前一篇文章中,笔者已经介绍了Java多线程的一些基础知识,但是想要成为一名中高级Java程序员还必须懂得Java并发包(JUC)的知识点,而且JUC ...

  5. python 多线程并发编程(生产者、消费者模式),边读图像,边处理图像,处理完后保存图像实现提高处理效率

    文章目录 需求 实现 先导入本次需要用到的包 一些辅助函数 如下函数是得到指定后缀的文件 如下的函数一个是读图像,一个是把RGB转成BGR 下面是主要的几个处理函数 在上面几个函数构建对应的处理函数 ...

  6. 网易云课堂微专业--Java高级开发工程师--多线程并发编程--学习笔记(二)

    文章目录 第一章 多线程并发编程 第二节 线程安全问题 1.2.1 线程安全之可见性问题 多线程中的问题 从内存结构到内存模型 工作内存缓存 指令重排序 内存模型的含义 Shared Variable ...

  7. JUC多线程并发编程

    1.什么是JUC 源码+官方文档 JUC是 java util concurrent 面试高频问JUC~! java.util 是Java的一个工具包~ 业务:普通的线程代码 Thread Runna ...

  8. Java多线程并发编程知识体系(附大图-持续更新)

    Java多线程体系 1.并发编程的优势 提升CPU资源利用率 提升吞吐量 提升程序响应速度 更好的编程模型 2.并发带来的问题 1.安全性问题 0.定义:什么是安全性问题 多线程读写共享变量时出现不正 ...

  9. 【2022】多线程并发编程面试真题

    文章目录 4. 多线程 4.1 创建线程有哪几种方式? 4.2 说说Thread类的常用方法 4.3 run()和start()有什么区别? 4.4 线程是否可以重复启动,会有什么后果? 4.5 介绍 ...

最新文章

  1. 【驱动】GNSS驱动:gpsOneXTRA 援助技术
  2. Linux 下打core并调试core
  3. graphpad多条不同的曲线_Graphpad作图,这些技巧你知道吗?
  4. 【Python】详解Python模块、包、库
  5. 从金蝶k3到金税盘_经典全套金蝶K3操作流程大全
  6. thttpd源码解析 定时器模块
  7. 如何设置Mac定时重启
  8. Wireshark 常用过滤
  9. block(块元素)、inline(内联元素)的差别是什么?
  10. 怎样给家庭组计算机授权,steam如何设置家庭共享?steam设置家庭共享方法
  11. 欧姆龙cp1h指令讲解_欧姆龙CP1H-XA40DT-D手册CP1H-XA40DT-D参考手册通信指令 - 广州凌控...
  12. 天刀各大服务器位置,天涯明月刀ol第十次合区详解 天刀ol第十次合区结果一览...
  13. 良田高拍仪集成WEB说明
  14. 计算机的优势和劣势_计算机专业毕业生考研还是就业应该怎么选?
  15. 阿里云 Teambition 网盘亲测体验,秀翻全网!
  16. 实例7:七段数码管绘制
  17. 2017ACM ICPC Asia Regional-Daejeon H-Rock Paper Scissors[ FFT]
  18. 【高德地图API】如何转到高德坐标系?
  19. STL剖析(二):容器底层数据结构及常见用法
  20. mysql没开启binlog恢复删除表_无全量备份、未开启binlog日志,利用percona工具恢复delete的数据...

热门文章

  1. monkey命令_何小伟:Monkey与MonkeyRunner区别
  2. vue weex 调用原生toast_vue-template-compiler 还能这么用
  3. xiaohai.cf index.php,php des 加密 - 北京破小孩
  4. Python,OpenCV应用轮廓逼近算法,检测对象的形状
  5. Java程序启动同时复制resources下文件到jar包同级目录
  6. 基于pytorch的模型剪枝+模型量化+BN合并+TRT部署(cifar数据)(2)
  7. Win10 + QT5.14.2 + Opencv4.1.1 编译环境搭建
  8. POJ - 3417 Network LCA+树上差分
  9. 【TensorFlow2.0】(1) tensor数据类型,类型转换
  10. java bag集合_集合基于数组的实现:ArrayBag.java