public class WaitTest {

     public void testWait(){
System.out.println("Start-----");
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End-------");
} public static void main(String[] args) {
final WaitTest test = new WaitTest();
new Thread(new Runnable() {
@Override
public void run() {
test.testWait();
}
}).start();
}
}
Exception in thread "Thread-0" Start-----
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at org.knowledge.muti.thread.waitNotify.WaitTest.testWait(WaitTest.java:15)
at org.knowledge.muti.thread.waitNotify.WaitTest$1.run(WaitTest.java:27)
at java.lang.Thread.run(Thread.java:745)

这段程序并没有按我们的预期输出相应结果,而是抛出了一个异常。大家可能会觉得奇怪为什么会抛出异常?而抛出的IllegalMonitorStateException异常又是什么?我们可以看一下JDK中对IllegalMonitorStateException的描述:

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor

这句话的意思大概就是:线程试图等待对象的监视器或者试图通知其他正在等待对象监视器的线程,但本身没有对应的监视器的所有权。wait方法是一个本地方法,其底层是通过一个叫做监视器锁的对象来完成的。所以上面之所以会抛出异常,是因为在调用wait方式时没有获取到monitor对象的所有权,那如何获取monitor对象所有权?Java中只能通过Synchronized关键字来完成,修改上述代码,增加Synchronized关键字


 public class WaitTest {

     public synchronized  void testWait(){
System.out.println("Start-----");
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End-------");
} public static void main(String[] args) {
final WaitTest test = new WaitTest();
new Thread(new Runnable() {
@Override
public void run() {
test.testWait();
}
}).start();
}
}

 

所以,通过这个例子,大家应该很清楚,wait方法的使用必须在同步的范围内,否则就会抛出IllegalMonitorStateException异常,wait方法的作用就是阻塞当前线程等待notify/notifyAll方法的唤醒,或等待超时后自动唤醒

notify/notifyAll方法

void notify() Wakes up a single thread that is waiting on this object's monitor.
void notifyAll() Wakes up all threads that are waiting on this object's monitor.

  有了对wait方法原理的理解,notify方法和notifyAll方法就很容易理解了。既然wait方式是通过对象的monitor对象来实现的,所以只要在同一对象上去调用notify/notifyAll方法,就可以唤醒对应对象monitor上等待的线程了。notify和notifyAll的区别在于前者只能唤醒monitor上的一个线程,对其他线程没有影响,而notifyAll则唤醒所有的线程,看下面的例子很容易理解这两者的差别:

public synchronized void testWait() {
System.out.println(Thread.currentThread().getName() + " Start-----"); try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " End-----"); } public static void main(String[] args) {
NotifyTest obj = new NotifyTest(); for (int i = 0; i < 5; i++) {
new Thread() { @Override
public void run() { obj.testWait();
};
}.start();
} synchronized (obj) { obj.notify();
}
Thread.sleep(3000);
System.out.println("-----------分割线-------------");
synchronized (obj) { obj.notifyAll(); } }

output:

p.p1 { margin: 0; font: 11px Monaco }


Thread-0 Start-----


Thread-4 Start-----


Thread-3 Start-----


Thread-2 Start-----


Thread-1 Start-----


Thread-0 End-----


====================notifyAll======


Thread-1 End-----


Thread-2 End-----


Thread-3 End-----


Thread-4 End-----

 

高并发之wait notify notifyAll原理详解的更多相关文章

  1. I2C 基础原理详解

    今天来学习下I2C通信~ I2C(Inter-Intergrated Circuit)指的是 IC(Intergrated Circuit)之间的(Inter) 通信方式.如上图所以有很多的周边设备都 ...

  2. 块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解

    CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...

  3. [转]js中几种实用的跨域方法原理详解

    转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...

  4. 【转】VLAN原理详解

    1.为什么需要VLAN 1.1 什么是VLAN? VLAN(Virtual LAN),翻译成中文是“虚拟局域网”.LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络.V ...

  5. LVS原理详解(3种工作方式8种调度算法)--老男孩

    一.LVS原理详解(4种工作方式8种调度算法) 集群简介 集群就是一组独立的计算机,协同工作,对外提供服务.对客户端来说像是一台服务器提供服务. LVS在企业架构中的位置: 以上的架构只是众多企业里面 ...

  6. LVS原理详解(3种工作模式及8种调度算法)

    2017年1月12日, 星期四 LVS原理详解(3种工作模式及8种调度算法)   LVS原理详解及部署之二:LVS原理详解(3种工作方式8种调度算法) 作者:woshiliwentong  发布日期: ...

  7. Namenode HA原理详解(脑裂)

    转自:http://blog.csdn.net/tantexian/article/details/40109331 Namenode HA原理详解 社区hadoop2.2.0 release版本开始 ...

  8. Storm概念、原理详解及其应用(一)BaseStorm

    本文借鉴官文,添加了一些解释和看法,其中有些理解,写的比较粗糙,有问题的地方希望大家指出.写这篇文章,是想把一些官文和资料中基础.重点拿出来,能总结出便于大家理解的话语.与大多数“wordcount” ...

  9. 201709019工作日记--sleep、wait、notify的使用详解

    1. sleep()和wait()的区分 (1)这两个方法来自不同的类分别是,sleep来自Thread类,wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在 ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:QTableWidget的findItems和selectedItems搜索项和访问选中项方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.搜索项 在表格部件中,可以根据文本以及匹配模式来搜索满足条件的项,调用语法: list[QTab ...

  2. Python正则表达式re.findall一个有趣的现象

    下面通过几个案例来分析一下, 注意:本节的parsematch函数请参考<妙用re.sub分析正则表达式解析匹配过程> 案例一: >>> re.findall(r&quo ...

  3. PyQt程序执行时报错:AttributeError: 'winTest' object has no attribute 'setCentralWidget'的解决方法

    用QtDesigner设计了一个UI界面,保存在文件Ui_wintest.ui中,界面中使用了MainWindow窗口,窗口名字也叫MainWindow,用PyUIC将其转换成了 Ui_wintest ...

  4. AutumnWater 秋水SRC平台

    持续给自己挖坑,简单介绍一下AutumnWater 秋水SRC平台趴: SRC开源漏洞响应平台 AutumnWater 秋水SRC平台 后端使用Python-Flask(蓝图)编写 前端使用少量VUE ...

  5. js- for in 循环 只有一个目的,遍历 对象,通过对象属性的个数 控制循环圈数

    for in 循环会返回 原型 以及原型链上面的属性,不会打印系统自带的属性 var obj ={  name:'suan',  sex :'male',  age:150,  height:185, ...

  6. tensorflow 指定版本安装

    首先,建议在anaconda中创建虚拟环境,教程已写,参考上一篇 下载之前建议设置pip清华源(用以提速,可百度) 设置下载源 pip config set global.index-url http ...

  7. WebRequest抓取网页数据出现乱码问题

    今天项目里突然有个功能用不起来了,本机确实好的 ,这个很无语 不知道为啥 经过写日志发现html 变成了这样的东西,很是头疼,刚开始各种编码转换,发现这并不是编码的问题 后面观察目标网站多了一个gzi ...

  8. 团队作业3_需求改进&系统设计

    一.需求&原型改进 1.需求改进: (1)发现问题:通过发布问卷调查及收集整理的形式发现用户的新需求: (2)修改需求:考虑新增提醒用户未完成事件的功能.   附:用户调查问卷(如下) 调研途 ...

  9. 【学习笔记】动态 dp 入门简易教程

    序列 dp 引入:最大子段和 给定一个数列 \(a_1, a_2, \cdots, a_n\)(可能为负),求 \(\max\limits_{1\le l\le r\le n}\left\{\sum_ ...

  10. 转:什么是Shingling算法

    shingling算法用于计算两个文档的相似度,例如,用于网页去重.维基百科对w-shingling的定义如下: In natural language processing a w-shinglin ...