目录

前言

一、wait()方法

wait()做的三件事

让wait()方法结束等待的条件

二、notify()方法

三、notifyAll()方法

总结

四、wait和sleep的对比【面试题】


前言

wait意思是等待,notify的意思是通知,它们的作用是协同多个线程的执行顺序

因为“抢占式执行”让两个线程的执行顺序充满了不确定性,所以我们希望通过wait和notify来控制线程的执行顺序,使线程之间可以更好的配合。

我们需要知道的是这两个方法都是Object(所以类的老祖宗)的方法

一、wait()方法

wait()做的三件事

1.让当前线程阻塞等待(把这个线程的PCB从就绪队列中放到阻塞队列中),准备接受通知

2.释放当前锁(要想使用wait()或者是notify(),就必须搭配synchronized,需要先获取到锁,然后才能谈wait())

3.需要满足一定的条件才能被唤醒,唤醒后重新尝试获取到这个锁

需要注意的是第一点和第二点需要以原子同时完成

让wait()方法结束等待的条件

1.其他线程调用该对象的notify()方法【最主要的用法】

我们已经知道了wait()和notify()都是Object的方法,就是说,如果线程1中的对象1调用了wait()方法,必须要有一个线程2,也调用对象1的notify()方法才能唤醒线程1,如果线程2调用对象2的notify()方法,是不能唤醒线程1的

public class ThreadDemo18 {public static void main(String[] args) throws InterruptedException {Object object=new Object();object.wait();object.notify();}
}

结果为

第一行的灰体带下滑线的意思是非法锁状态

如果没有把wait放到synchronized内部,就能看到这个异常

调用wait的对象和锁对象必须是同一个

public class ThreadDemo18 {public static void main(String[] args) throws InterruptedException {Object object=new Object();synchronized (object){System.out.println("wait之前");object.wait();System.out.println("wait之后");}}
}

结果为

从结果我们可以看出现在这个线程已经进入了阻塞队列中,我们也可以从jconsole.exe看出这个线程正在进行等待

如果我们不对这个程序做什么的话这个线程就会永远等待下去,此时我们需要做点什么来使得这个线程等待状态结束,这里我们引入了notify方法

二、notify()方法

关于notify方法的使用

1.也需要放到synchronized中使用

2.notify操作是一次唤醒一个线程,如果是有多个线程都在等待中,调用notify就相当于是随机唤醒了一个,其它线程保持原状

3.调用notify是通知对方被唤醒,但是调用notify方法的线程并不是立刻释放锁,而是要等待当前的synchronized代码块执行完才释放锁(notify本身不会释放锁)

代码实例

public class ThreadDemo19 {static class WaitTask implements Runnable{private Object locker=null;public WaitTask(Object locker) {this.locker = locker;}@Overridepublic void run() {//进行wait的线程synchronized (locker){System.out.println("wait开始前");try {//直接调用wait,相当于this.wait(),也就是针对WaitTask的对象进行等待//但是我们需要在下面在NotifyTask类中针对同一个对象进行通知//然而,在NotifyTask中拿到WaitTask的对象并不容易locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait结束");}}}static class NotifyTask implements Runnable{private Object locker=null;public NotifyTask(Object locker) {this.locker = locker;}@Overridepublic void run() {//进行notify的线程synchronized (locker){System.out.println("notify开始前");locker.notify();System.out.println("notify结束");}}}public static void main(String[] args) throws InterruptedException {//所以为了解决上述问题,我们需要专门建一个对象,去负责加锁/通知操作Object locker=new Object();Thread t1=new Thread(new WaitTask(locker));Thread t3=new Thread(new WaitTask(locker));Thread t4=new Thread(new WaitTask(locker));Thread t2=new Thread(new NotifyTask(locker));t1.start();t3.start();t4.start();Thread.sleep(3000);t2.start();}
}

运行结果为

三、notifyAll()方法

notify方法一次只能唤醒一个线程,而notifyAll可以唤醒多个,虽然多个线程都被唤醒了,但这几个线程执行还是有先后顺序的原因是这几个线程还要竞争锁

public void run() {//进行notify的线程synchronized (locker){System.out.println("notify开始前");locker.notifyAll();System.out.println("notify结束");}}

运行结果为

2.wait()等待时间超时

3.其它线程调用该等待线程的interrupted()方法,导致wait抛出InterruptedExpectation异常

总结

notify是一次唤醒一个,而notifyAll是一次唤醒一堆,具体用哪个还要看具体场景,一般来说用的是notify

四、wait和sleep的对比【面试题】

1.sleep操作是指定一个固定时间来阻塞等待,而wait既可以指定时间,也可以无限等待

2.wait可以通过notify或interrupt或时间到来唤醒,sleep通过interrupt或时间到唤醒

3.wait的主要用途是为了协调线程之间的先后顺序,而sleep单纯是让线程休眠,并没涉及到多个线程的配合

wait和notify方法相关推荐

  1. 对象的notify方法的含义和对象锁释放的三种情况

    1,notify的含义     (1)notify一次只随机通知一个线程进行唤醒 (2)在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁, 要等到 ...

  2. Java线程的挂起与恢复 wait(), notify()方法介绍

    一, 什么是线程的挂起与恢复 从字面理解也很简单. 所谓线程挂起就是指暂停线程的执行(阻塞状态). 而恢复时就是让暂停的线程得以继续执行.(返回就绪状态) 二, 为何需要挂起和恢复线程. 我们来看1个 ...

  3. java wait源码_Java精通并发-透过openjdk源码分析wait与notify方法的本地实现

    上一次https://www.cnblogs.com/webor2006/p/11442551.html中通过openjdk从c++的底层来审视了ObjectMonitor的底层实现,这次继续来探究底 ...

  4. java并发锁获取的方式_Java精通并发-notify方法详解及线程获取锁的方式分析

    wait(): 在上一次https://www.cnblogs.com/webor2006/p/11404521.html中对于无参数的wait()方法的javadoc进行了解读,而它是调用了一个参数 ...

  5. 多线程笔记补充之线程通信wait和notify方法以及Lock和Condition接口的使用

    线程通信-wait和notify方法介绍: java.lang.Object类提供类两类用于操作线程通信的方法. wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中,等待其他的 ...

  6. java thread.notify_Java Thread notify()方法

    Thread类的notify()方法用于唤醒单个线程. 此方法仅为一个等待特定对象的线程提供通知. 如果使用notify()方法并且有多个线程正在等待通知,那么只有一个线程获得通知,而剩下的线程必须等 ...

  7. 调用notify方法

    public class ThreadCommunicateTest implements Runnable{private int cnt=1;@Overridepublic void run(){ ...

  8. 线程wait和notify方法

    一.等待和通知 wait和notify也是为了处理线程调度随机性的问题的,但是这个随机性不太好,还是需要让彼此之间有一个固定的顺序的,join也是一种控制顺序的方式,更倾向于控制线程结束,也是有局限性 ...

  9. Java学习: wait和notify方法、ThreadLocal

    wait方法和notift方法 其实我们之前可能就发现了,Object类还有三个方法我们从来没有使用过,分别是wait().notify()以及notifyAll(),他们其实是需要配合synchro ...

最新文章

  1. server 2008 中活动目录的迁移
  2. python 封装_python接口自动化学习笔记(封装方法用于读取excel)
  3. 浅谈自然语言在科技时代的运用
  4. 字符串-判断数字的三个方法
  5. WebSocket服务器和客户端的一对多通知实现
  6. Linux下读写芯片的I2C寄存器
  7. C++ Primer 有感(重载操作符)
  8. sizeof(class)分析
  9. 赚钱的基本逻辑就是价值交换
  10. matlab计数器清零,51单片机计数器清零
  11. SCM供应链管理系统的优点
  12. 【数据库技术与应用】Part01——数据库系统概述
  13. mysql identity属性_Mysql中Identity 详细介绍
  14. jquery 获取上传图片的大小
  15. 4k视频写入速度要求_4K视频要用什么卡?极速专业存储卡盘点
  16. 官场直升机 鸿蒙笔著,担当和尚:老衲笔尖无墨水,要从空处想鸿蒙
  17. 智能电视也进入消费者重视芯片的时代了
  18. 控制结构(强化):12.阿迪玩游戏
  19. Y - 献给杭电五十周年校庆的礼物
  20. 如图,甲乙两人分别在AB两地同时相向而行,于E处相遇后,甲继续向B地行走,乙则休息了14分钟,在继续向A地行走,甲和乙到达B和A后立即折返,又在E处相遇,已知甲每分钟行走60米,乙每分钟行走80米

热门文章

  1. 图形编辑器:拖拽阻塞优化
  2. 控制翻页c语言,阅读器多种翻页的设计与实现
  3. 攻防世界-MISC-练习区-06(坚持60s)
  4. 《算法笔记》9.4小节 9.5小节——数据结构专题(2)->二叉查找树(BST)->平衡二叉树(AVL)
  5. PAT_乙级_1001_筱筱
  6. 消息队列——RabbitMQ消息队列集群
  7. VsCode同步配置到另一台设备
  8. 大数据学长面试之boss直聘面试题
  9. linux 模拟arm,拒绝开发板, 用 SkyEye 就可以模拟 ARM Linux!
  10. 信息系统安全管理架构