Java多线程_wait/notify/notifyAll方法
关于这三个方法,我们可以查询API得到下列解释:
wait():导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法或者指定的事件用完
notify():唤醒在此对象监视器上等待的单个线程
notifyAll():唤醒在此对象监视器上等待的所有线程
我们需要注意的点
(1)wait()、notify/notifyAll() 方法是Object的本地final方法,无法被重写。
(2)wait() 与 notify/notifyAll 方法必须在同步代码块中使用。
(3)由于 wait() 与 notify/notifyAll() 是放在同步代码块中的,因此线程在执行它们时,肯定是进入了临界区中的,即该线程肯定是获得了锁的。
(4)当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。
(5)当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下 执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。
(6)如果在执行wait() 与 notify/notifyAll() 之前没有获得相应的对象锁,就会抛出:java.lang.IllegalMonitorStateException异常。
下面我们看代码:
public class WaitNotifyDemo {
public static void main(String[] args) {
Object lock = new Object();
WaitMathodThread w = new WaitMathodThread(lock);
w.start();
NotifyMethodThread n = new NotifyMethodThread(lock);
n.start();
}
public void waitMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin wait() ThreadName=" + Thread.currentThread().getName());
lock.wait();
System.out.println(" end wait() ThreadName=" + Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void notifyMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin notify() ThreadName=" + Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
lock.notify();
Thread.sleep(5000);
System.out.println(" end notify() ThreadName=" + Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class WaitMathodThread extends Thread {
private Object lock;
public WaitMathodThread(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
WaitNotifyDemo wnd = new WaitNotifyDemo();
wnd.waitMethod(lock);
}
}
class NotifyMethodThread extends Thread {
private Object lock;
public NotifyMethodThread(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
WaitNotifyDemo wnd = new WaitNotifyDemo();
wnd.notifyMethod(lock);
}
}
运行结果:

从这个测试中可以看出调用了wait()方法后会立即释放锁,线程进入等待状态,而调用了notify()方法后并不会立即释放锁,会等到走完synchronized修饰的临界区时,才会释放锁。
所以一般在调用了notify()方法后最好马上退出synchronized修饰的临界区。
Java多线程_wait/notify/notifyAll方法的更多相关文章
- Java多线程--wait(),notify(),notifyAll()的用法
忙等待没有对运行等待线程的 CPU 进行有效的利用(而且忙等待消耗cpu过于恐怖,请慎用),除非平均等待时间非常短.否则,让等待线程进入睡眠或者非运行状态更为明智,直到它接收到它等待的信号. Java ...
- java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?
wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity.所有对象的非同步方法都能够在任意时刻被任意线程调用 ...
- java多线程中用到的方法详细解析
在多线程学习的过程中涉及的方法和接口特别多,本文就详细讲解下经常使用方法的作用和使用场景. 1.sleep()方法. 当线程对象调用sleep(time)方法后,当前线程会等待指定的时间(t ...
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
在 Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity. 所有对象的非同步 方法都能够在任意时刻被任意线 ...
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- java使用wait(),notify(),notifyAll()实现等待/通知机制
public class WaitNotify { static boolean flag=true; static Object lock=new Object(); static class Wa ...
- 为什么 wait()方法和 notify()/notifyAll()方法要在同步块 中被调用 ?
这是 JDK 强制的,wait()方法和 notify()/notifyAll()方法在调用前都必须先获得对 象的锁
- Java多线程 wait, notify 和 notifyAll
Java的Object类 public class Object { public final native void notify(); public final native void notif ...
随机推荐
- 可能会用的到的JQ插件
├─lib │ jquery jQuery类库(v1.9.1) │ bootstrapSwitch 开关控件 │ Hui-iconfont_v1.0 阿里图标字体库(H-ui定制) │ font-aw ...
- FPAG_Microblaze_PWM_定时器
由于Xilinx底层库的定时器没有PWM例程,调试过程中费了不少劲.生产PWM需要两个定时器同时工作,一个控制频率,一个控制占空比,位数可通过硬件设置. #include "xtmrctr_ ...
- PHP password_hash() 函数
password_hash() 函数用于创建密码的散列(hash) PHP 版本要求: PHP 5 >= 5.5.0, PHP 7高佣联盟 www.cgewang.com 语法 string p ...
- Skill art函数遍历字典
https://www.cnblogs.com/yeungchie/ code procedure(ycartGo(length1) prog(() for(x 1 length1 printf(&q ...
- IDEA-Translation最优秀的翻译插件
IDEA最优秀的翻译插件 效果 特性 多翻译引擎 Google翻译 有道翻译 百度翻译 多语言互译 文档翻译 语音朗读 自动选词 自动单词拆分 单词本 使用 申请有道智云翻译服务(可选): 注册有道智 ...
- Android VideoView未解决,动态读取权限、BottomNavigationView的用法
昨天想写的,但是因为Video的毛病,是真找不出为啥了.百度也没用,学长也不清楚. 百度了那么久,大概得出结论,电脑的视频是不能用它来播放的... ..经过两天的奋斗,我居然搞定了,我的视频终于出来了 ...
- 使用Luhn算法实现信用卡号验证
问题描述: 2:信用卡号的验证 [信用卡号的验证] 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么 担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过 Luhn 算法 ...
- Coders' Legacy 2020 题解
目录 Chef vs Doof Doof on Cartesian Doof fires Brackets Jeremy gets a gift Unique Substring Perry lear ...
- data argumentation 数据增强汇总
几何变换 flip:水平翻转,也叫镜像:垂直翻转 rotation:图片旋转一定的角度,这个可以通过opencv来操作,各个框架也有自己的算子 crop:随机裁剪,比如说,在ImageNet中可以将输 ...
- Redis服务之集群节点管理
上一篇博客主要聊了下redis cluster的部署配置,以及使用redis.trib.rb工具所需ruby环境的搭建.使用redis.trib.rb工具创建.查看集群相关信息等,回顾请参考https ...