轮询

线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作。

想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处理?一个办法就是,B线程while(i == 10000),这样两个线程之间就有了通信,B线程不断通过轮训来检测i == 10000这个条件。

这样可以实现我们的需求,但是也带来了问题:CPU把资源浪费了B线程的轮询操作上,因为while操作并不释放CPU资源,导致了CPU会一直在这个线程中做判断操作。如果可以把这些轮询的时间释放出来,给别的线程用,就好了。

wait/notify

在Object对象中有三个方法wait()、notify()、notifyAll(),既然是Object中的方法,那每个对象自然都是有的。如果不接触多线程的话,这两个方法是不太常见的。下面看一下前两个方法:

1、wait()

wait()的作用是使当前执行代码的线程进行等待,将当前线程置入"预执行队列"中,并且wait()所在的代码处停止执行,直到接到通知或被中断。在调用wait()之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()方法。

2、notify()

notify()的作用是,如果有多个线程等待,那么线程规划器随机挑选出一个wait的线程,对其发出通知notify(),并使它等待获取该对象的对象锁。注意"等待获取该对象的对象锁",这意味着,即使收到了通知,wait的线程也不会马上获取对象锁,必须等待notify()方法的线程释放锁才可以。和wait()一样,notify()也要在同步方法/同步代码块中调用。

总结起来就是,wait()使线程停止运行,notify()使停止运行的线程继续运行。

wait()/notify()使用示例

看一段代码:

写个main函数,同样的Thread.sleep(3000)也是为了保证mt0先运行,这样才能看到wait()和notify()的效果:

看一下运行结果:

第一行和第二行之间的time减一下很明显就是3s,说明wait()之后代码一直暂停,notify()之后代码才开始运行。

wait()方法可以使调用该线程的方法释放共享资源的锁,然后从运行状态退出,进入等待队列,直到再次被唤醒。

notify()方法可以随机唤醒等待队列中等待同一共享资源的一个线程,并使得该线程退出等待状态,进入可运行状态

notifyAll()方法可以使所有正在等待队列中等待同一共享资源的全部线程从等待状态退出,进入可运行状态

最后,如果wait()方法和notify()/notifyAll()方法不在同步方法/同步代码块中被调用,那么虚拟机会抛出java.lang.IllegalMonitorStateException,注意一下。

wait()释放锁以及notify()不释放锁

多线程的学习中,任何地方都要关注"锁",wait()和notify()也是这样。wait()方法是释放锁的,写一个例子来证明一下:

如果wait()方法不释放锁,那么Thread-1根本不会进入同步代码块打印的,所以,证明完毕。

接下来证明一下notify()方法不释放锁的结论:

写两个线程分别调用2个方法:

看一下运行结果:

如果notify()方法释放锁,那么在Thread-1调用notify()方法后Thread.sleep(5000)必定应该有其他线程可以进入同步代码块了,但是实际上没有,必须等到Thread-1把代码执行完。所以,证明完毕。

interrupt()打断wait()

之前有说过,interrupt()方法的作用不是中断线程,而是在线程阻塞的时候给线程一个中断标识,表示该线程中断。wait()就是"阻塞的一种场景",看一下用interrupt()打断wait()的例子:

notifyAll()唤醒所有线程

利用Object对象的notifyAll()方法可以唤醒处于同一监视器下的所有处于wait的线程,举个例子证明一下:

写两个线程,一个调用testMethod(Object lock)的线程,一个notifyAll()线程:

main函数开三个wait线程,用一个notifyAll的线程去唤醒:

当然,唤醒的顺序不重要,因为notifyAll()把处于同一资源下wait的线程全部唤醒,至于唤醒的顺序,就和线程启动的顺序一样,是虚拟机随机的。

java 多线程 notify_Java多线程8:wait()和notify()/notifyAll()相关推荐

  1. java线程的生命周期及wait(),notify(),notifyAll()的详解分析

    1.java线程的生命周期     线程是一个动态执行的过程,它也有一个从产生到死亡的过程. (1)生命周期的五种状态 新建(new Thread)     当创建Thread类的一个实例(对象)时, ...

  2. java多线程notify_Java多线程 wait notify

    源码 java public final native void notify(); public final native void notifyAll(); public final void w ...

  3. 多线程并发的解决方案 volatile synchronized notify notifyAll wait关键字分析

    2019独角兽企业重金招聘Python工程师标准>>> 1.ThreadLocal用法 在java中,如果一个变量需要被多个线程访问,可以使用volatile来声明它为"易 ...

  4. java线程wait_java多线程学习(四) 之 wait和notify

    ynchronized让线程之间互斥,但是有时候因为业务逻辑,需要主动释放锁,让其它的线程执行,这就需要线程之间通信,我们知道JAVA里每个对象都有个隐式锁,JAVA为每个对象都提供了wait和not ...

  5. Java基础——Java多线程中sleep()、wait()和notify()

    一.sleep() sleep()方法源码: /** * Causes the currently executing thread to sleep (temporarily cease * exe ...

  6. Java 多线程 4:wait() 和 notify()/notifyAll()

    轮询快速到底 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A 线程做 int 型变量 i 的累加操作,B 线程等待 i 到了 1 ...

  7. java 多线程 notifyall_java多线程之 wait(),notify(),notifyAll()

    这几天在写一个java多线程服务器的功能,用到这些基础,自叹基础知识还需巩固,先写上一下这些说明,供自己和大家参考 wait(),notify(),notifyAll()不属于Thread类,而是属于 ...

  8. Java多线程学习之wait、notify/notifyAll 详解

    点击"终码一生",关注,置顶公众号 每日技术干货,第一时间送达! 1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2. ...

  9. java多线程notifyall_Java多线程:线程状态以及wait(), notify(), notifyAll()

    1. wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前 ...

最新文章

  1. 解密Kernel:为什么适用任何机器学习算法?
  2. 服务器 'xxxx' 已被定义为分发服务器。若要将该服务器重新配置为分发服务器,必须首先卸载现有的分发服务...
  3. 为什么写博客?如何在博客中更好的分享?
  4. 【整理】电容知识小结(二)
  5. eclipsejvm内存不足_Eclipse无法调试及编译时内存不足的解决
  6. python帮助文档中查看内置函数_PYTHON官方文档内置函数整理
  7. 应用C语言编辑画图程序
  8. Register DLL and OCX
  9. 更新CentOS中的python(从2.6.X到2.7.X)
  10. 正阅读微信小说分销系统-视频教程-4.数据统计 包含图文教程
  11. php递归函数名字,php递归函数
  12. 阿里云盘内测_阿里云盘即将推出,欲与百度网盘较高下
  13. 【jQuery】jQuery对象与prevObject
  14. VMware提示“指定的文件不是虚拟磁盘“或“The file specified is not a virtual disk”打不开
  15. ViewBinding使用时出现Could not find method viewBinding() for arguments错误
  16. android 电子签名设备,[Android]实现电子签名并截屏
  17. 工具说明书 - 如何画时间轴(Timeline)
  18. Linux centOS系统备份还原(dd+rsync方式)
  19. 2012年奇虎360校园招聘实习生笔试编程题
  20. VR全景拍摄如何拍摄?如何使用拍摄器材?

热门文章

  1. python 匹配字符串map lambda函数_Python map amp; reduce 以及lambda匿名函数 - jvisualvm - ITeye博客...
  2. c语言音像店程序,音像店管理程序_C 课程设计.pdf
  3. latex的基本使用
  4. mysql联合索引like_MySQL全文索引、联合索引、like查询、json查询速度大比拼
  5. linux装服务器系统,linux服务器系统安装
  6. 无法执行二进制文件: 可执行文件格式错误_VB中.frm .frx .vbp .vbw .scc文件都有什么作用,你知道么?...
  7. python打开文件_用Python(in PsychoPy)打开SPSS数据文件
  8. python数字形式转换_在Python中将字母转换为数字
  9. matplot绘制图形入门
  10. Python正则表达式re.sub使用