Object wait():使一个线程处于等待状态,释放CPU和锁资源

Java Doc 关于 wait 方法的说明如下:

Causes the current thread to wait until either another thread invokes

The current thread must own this object's monitor. // 否则: IllegalMonitorStateException(正在等待的对象没有锁)

In other words, waits should always occur in loops, like this one: //(防止虚假唤醒 spurious wakeup)

synchronized (obj) {while (<condition does not hold>) {obj.wait(timeout);}... // Perform action appropriate to condition
}

线程执行wait方法进入等待后会进入对象的一个等待集合,在以下四种情况下会被唤醒

1.当其他线程调用类notify方法,而恰好当前线程被选择为唤醒线程

2.其他线程调用了notifyAll()方法

3.线程被其他线程中断

4.wait到达了等待的最大时间。如果该时间被设置为0在这种情况不成立,线程会一直等待下去

在Javadoc中特别声明了,在使用wait方法时,最好将wait放在一个loop循环中,因为wait有很小的机率在不通过以上四种方法的情况下被唤醒,该唤醒被称为伪唤醒。

如果不把wait写入loop中,那么有可能导致线程异常执行

Spurious Wakeups

http://tutorials.jenkov.com/java-concurrency/thread-signaling.html

For inexplicable reasons it is possible for threads to wake up even if notify() and notifyAll() has not been called. This is known as spurious wakeups. Wakeups without any reason.(唤醒原因尚不明确)

If a spurious wakeup occurs in the MyWaitNofity2 class's doWait() method the waiting thread may continue processing without having received a proper signal to do so! This could cause serious problems in your application.

To guard against spurious wakeups the signal member variable is checked inside a while loop instead of inside an if-statement. Such a while loop is also called a spin lock. The thread awakened spins around until the condition in the spin lock (while loop) becomes false. Here is a modified version of MyWaitNotify2 that shows this:

public class MyWaitNotify3{MonitorObject myMonitorObject = new MonitorObject();boolean wasSignalled = false;public void doWait(){synchronized(myMonitorObject){while(!wasSignalled){try{myMonitorObject.wait();} catch(InterruptedException e){...}}//clear signal and continue running.wasSignalled = false;}}public void doNotify(){synchronized(myMonitorObject){wasSignalled = true;myMonitorObject.notify();}}
}

Notice how the wait() call is now nested inside a while loop instead of an if-statement. If the waiting thread wakes up without having received a signal, the wasSignalled member will still be false, and the while loop will execute once more, causing the awakened thread to go back to waiting

当程序调用 wait () 方法之后进入 WAITING 状态,预期 wasSignalled 值设置为 true 后被 notify()

如果被虚假唤醒,此时 wasSignalled值依然为(false),不满足预期, 所以需要对预期条件重复校验,即 while(!wasSignalled)

Java - Object wait() 方法之虚假唤醒spurious wakeup相关推荐

  1. 多线程并发编程需要注意虚假唤醒Spurious wakeup

    虚假唤醒  Spurious wakeup 如果等待线程在没有通知被调用的情况下唤醒,则称为Spurious wakeup. 解决方案就是: 使用while条件判断,更好的方案是避免使用wait这种低 ...

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

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

  3. Java Object.hashCode()方法

    Java Object.hashCode()方法 @(JAVA)[java] 更详细的内容可以参考<effective java>与<think in java> Object ...

  4. 条件变量的虚假唤醒(spurious wakeups)问题

    引言 条件变量是我们常用的同步原语之一,它的正确使用方式一般如下图: 在wait端,我们必须把判断布尔条件和wait()放到while循环中,而不能用if语句,原因是可能会引起虚假唤醒. 那么,究竟什 ...

  5. java suprious wakeup_多线程编程中条件变量和的spurious wakeup 虚假唤醒

    1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1)线程等待某 ...

  6. linux虚假唤醒(spurious wakeup)

    1.Linux对虚假唤醒的说明 On a multi-processor, it may be impossible for an implementation of pthread_cond_sig ...

  7. java线程打水问题_Java 多线程 wait() 虚假唤醒问题

    本文分享 wait()  的虚假唤醒(Spurious Wakeups)问题,会说明什么是虚假唤醒,以及如何解决. 先看一下相关的 java doc: java doc 说由于中断和虚假唤醒可能会发生 ...

  8. java wait 参数_Java Object wait()方法

    Java Object wait()方法 java.lang.Object.wait(long timeout, int nanos) 导致当前线程等待,直到其他线程调用此对象的 notify() 方 ...

  9. C++条件变量Wait及虚假唤醒

    (1) wait(lock): 调用时即阻塞线程,并且调用lock.unlock() (2) wait(lock, conditions): 调用时检查conditions,如果为false,则阻塞线 ...

  10. Java多线程之线程虚假唤醒

    Java多线程之线程虚假唤醒 本文目录提纲 问题:两个线程对一个初始值为零的变量操作,实现一个线程加一,另一个线程减一,来十次. 问题:四个线程对一个初始值为零的变量操作,实现两个线程加一,另外两个线 ...

最新文章

  1. 一图读懂:中国科学院“基础研究十条”
  2. 数据结构简介以及抽象数据类型的实现
  3. css 科技 边框_CSS 边框
  4. java 负数存储结构_负数在java中的存储和读取过程 | 学步园
  5. 人工神经网络心得体会_卷积神经网络学习心得
  6. MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解...
  7. canvas图形绘制
  8. MVC-Chart_WebGrid 显示漂亮chart
  9. 混合式教学模式在课堂中的应用
  10. mac 中word去掉超链接
  11. c++调用opencv实现图片叠加以及添加水印效果
  12. 智能数据构建与管理(Dataphin)-资产全景
  13. Vue学习随笔+商城项目【上】
  14. ffmpeg提取mp4文件中的音频,保存为wav文件
  15. C++的数据复合类型
  16. 【个人总结】2020计算机保研经历(北大信科、上交、浙大、南大、中科院)
  17. Ubuntu 下用tar 命令打包文件
  18. 芝加哥大学计算机语言学,2020年芝加哥大学CS排名,真得认真的去考查
  19. vue实现登录路由跳转到成功页面
  20. a different object with the same

热门文章

  1. SSM项目源码基于SSM实现的小说网站含前后台
  2. 企业微信通讯录可以导出吗?如何导出?
  3. 整数变百分数C语言,整数百分比
  4. 微信授权登陆服务器,微信公众号开发流程--微信第三方授权登陆流程
  5. sonic云真机入门教程
  6. 微信公众号之微信退款
  7. 小学-知识与能力【5】
  8. 在CSDN持续写博客半年之后,我的薪资涨了45%
  9. 正态分布方法判别,独立样本T检验及Mann-Whitney U 检验操作
  10. 【转载】白素贞的身世之谜