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

  • Signaling via Shared Objects
  • Busy Wait
  • wait(),notify() and notifyAll()
  • Missed Signals
  • Spurious Wakeups
  • Multiple Threads Waiting for the Same Signals
  • Don’t call wait() on constant String’s or global objects

线程信号的目的是为了线程间能够相互发送信号,并且也能使线程去等待其他线程的信号。例如一个线程B可能等待一个来至于线程A的信号,用来表明数据已经处理好了。

Signaling via Shared Objects

一种简单的线程通信(线程间进行信号的发送)是使用共享相同的对象变量。

    public class MySignal {protected boolean hasDataToProcess = false;public synchronized boolean hasDataToProcess() {return this.hasDataToProcess;}public synchronized void setHasDataToProcess(boolean hasData) {this.hasDataToProcess = hasData;}}

多个线程必须共享同一个变量。

Busy Wait

一个线程一直在等待另外一个线程改变共享变量的为其期望值,称为 Busy Wait。

protected MySignal sharedSignal = ...
...
while(!sharedSignal.hasDataToProcess()){//do nothing... busy waiting
}

wait(),notify() and notifyAll()

Busy waiting 不是一种非常有效地利用CPU来运行等待线程,即容易造成CPU的浪费,除非等待线程所耗费的时间非常短。更好的方式waiting thread 能够sleep或者inactive当接受到等待信号时。
Java中使用wait(),notify(),notifyAll()来完成这些工作。

A thread that calls wait() on any object becomes inactive until another thread calls notify() on that object. In order to call either wait() or notify the calling thread must first obtain the lock on that object. In other words, the calling thread must call wait() or notify() from inside a synchronized block. Here is a modified version of MySignal called MyWaitNotify that uses wait() and notify().

也就是说,wait、notify、notifyAll必须加上synchronized关键字,且所对象必须是用一个对象。

    public class MyWaitNotify {MonitorObject myMonitorObject = new MonitorObject();public void doWait() {synchronized (myMonitorObject) {try {myMonitorObject.wait();} catch (InterruptedException e) {...}}}public void doNotify() {synchronized (myMonitorObject) {myMonitorObject.notify();}}}

Missed Signals

如果一个线程在调用wait时先调用了notify,容易出现信号丢失的情况,直接导致线程waiting forever

    public class MyWaitNotify2 {MonitorObject myMonitorObject = new MonitorObject();boolean wasSignalled = false;public void doWait() {synchronized (myMonitorObject) {if (!wasSignalled) {//  In fact it only calls wait() if no signal was received in between the previous doWait() call and this.try {myMonitorObject.wait();} catch (InterruptedException e) {...}}//clear signal and continue running.wasSignalled = false;}}public void doNotify() {synchronized (myMonitorObject) {wasSignalled = true;myMonitorObject.notify();}}}

Spurious Wakeups

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.

    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();}}}

Multiple Threads Waiting for the Same Signals

The while loop is also a nice solution if you have multiple threads waiting, which are all awakened using notifyAll(), but only one of them should be allowed to continue. Only one thread at a time will be able to obtain the lock on the monitor object, meaning only one thread can exit the wait() call and clear the wasSignalled flag. Once this thread then exits the synchronized block in the doWait() method, the other threads can exit the wait() call and check the wasSignalled member variable inside the while loop. However, this flag was cleared by the first thread waking up, so the rest of the awakened threads go back to waiting, until the next signal arrives.

Don’t call wait() on constant String’s or global objects

不要使用String类型去做锁对象,因为在编译期间很多常量String都会直接放入常量池中,被共享。

    public class MyWaitNotify{String myMonitorObject = "";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();}}}

Java — Thread Signaling相关推荐

  1. (转)性能分析之-- JAVA Thread Dump 分析综述

    原文链接:http://blog.csdn.net/rachel_luo/article/details/8920596 最近在做性能测试,需要对线程堆栈进行分析,在网上收集了一些资料,学习完后,将相 ...

  2. 三个实例演示 Java Thread Dump 日志分析

    jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注) 执行中,Runnable 等待资源,Waiting on condition ...

  3. 各种 Java Thread State 第一分析法则

    用 TDA 工具,看到大量 Java Thread State 的第一反应是: 1,线程状态为"waiting for monitor entry": 意味着它 在等待进入一个临界 ...

  4. java Thread sleep 和obj.wait,以及sychronized,minor源码

    sleep()方法是Thread类里面的,主要的意义就是让当前线程停止执行,让出cpu给其他的线程,但是不会释放对象锁资源以及监控的状态,当指定的时间到了之后又会自动恢复运行状态. wait()方法是 ...

  5. linux非守护线程一直不释放,Linux pthread 和 java thread 的是 / 非守护线程的行为

    Linux pthread 和 java thread 的是 / 非守护线程的行为 pthread_xxx 的函数并没有直接提供设置一个 pthread 为守护线程的 API 而 pthread_at ...

  6. java thread join()_Java Thread join() 的用法

    Java Thread中, join() 方法是让调用该方法的主线程执行run()时暂时卡住,等run()执行完成后, 主线程再调用执行join()后面的代码.示例: class ThreadTest ...

  7. Java Thread

    Java Thread 使用Java多线程编程很容易. Java线程总是实现接口java.lang.Runnable, 一般有两种方法: 创建一个类实现接口Runnable, 创造该类的实例作为参数传 ...

  8. java thread join()_Java中Thread.join()的使用方法

    概要 本文分三个部分对thread.join()进行分析: 1. join() 的示例和作用 2. join() 源码分析 3. 对网上其他分析 join() 的文章提出疑问 1. join() 的示 ...

  9. Jvm处理Java Thread 的run方法中抛出异常的流程

    Jvm处理Java Thread 的run方法中抛出异常的流程 参考文章: (1)Jvm处理Java Thread 的run方法中抛出异常的流程 (2)https://www.cnblogs.com/ ...

最新文章

  1. 微信小程序开发视频教程新鲜出炉
  2. IHttpModule
  3. android SurfaceView
  4. 基准测试:Apache Ignite仍然领先于Hazelcast
  5. 腾讯,字节等大厂面试真题汇总,进阶学习资料!
  6. scrapy 分布式 mysql_Scrapy基于scrapy_redis实现分布式爬虫部署的示例
  7. 从零开始做一个工业级别的实时换脸程序
  8. 霸榜6个月!超60000+程序员关注!这个 AI 课凭什么成为畅销经典?
  9. 2019春运大幕即将开启 西安动车列车员整装迎春运
  10. 推荐一款个人感觉比较舒服的idea主题
  11. 儿童时间管理表,让孩子学会善待时间
  12. Eoapi — 一个可拓展的开源 API 工具
  13. STM32F103C8T6最小系统原理图和PCB
  14. ZK宕机重启数据恢复
  15. C语言实现乘法原理,伽罗华乘法原理与C语言实现
  16. 解决 SysFader:iexplore.exe应用程序错误
  17. 【GDKOI2013】琪露诺的完美算法课
  18. workerman wss 配置备忘录
  19. 第九届蓝桥杯 省赛 C语言A组
  20. 小米手机用什么耳机音质好?发烧级音质蓝牙耳机推荐

热门文章

  1. C++混合中文英文字符串匹配查找改进
  2. 【引用】空间曲线的切线、主法线、副法线
  3. poi导出Excel设置超链接-简便方法
  4. 走近棒球运动·巴尔的摩金莺队·MLB棒球创造营
  5. 分享111个ASP留言日记源码,总有一款适合您
  6. Python实现SPN加密算法
  7. CodeForces - 11D A Simple Task
  8. 襄樊公交信息化管理企划书
  9. 移动医疗平台遭遇“挂号滑铁卢”
  10. FAST-LIO, ikd-Tree, FAST-LIO2, FASTER-LIO论文总结