一.wait()、notify()和notifyAll()

为了更好的支持多线程之间的协作,JDK提供了三个重要的本地方法

//调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的锁.public final void wait() throws InterruptedException {wait(0);}
//调用某个对象的notify()方法能够唤醒一个正在等待这个对象的锁的线程,如果有多个线程都在等待这个对象的锁,则只能唤醒其中一个线程public final native void notify();
//notifyAll()方法能够唤醒所有正在等待这个对象锁的线程;public final native void notifyAll();

如图:当一个拥有Object锁的线程调用 wait()方法时,就会使当前线程加入object.wait 等待队列中,并且释放当前占用的Object锁,这样其他线程就有机会获取这个Object锁,获得Object锁的线程调用notify()方法,就能在Object.wait 等待队列中随机唤醒一个线程(该唤醒是随机的与加入的顺序无关,优先级高的被唤醒概率会高),若果调用notifyAll()方法就唤醒全部的线程。注意:调用notify()方法后并不会立即释放object锁,会等待该线程执行完毕后释放Object锁。

代码:

public class WaitTest {private static Object object=new Object();public static void main(String[] args) {Thread thread=new Thread(){@Overridepublic void run() {synchronized (object) {System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"进入启动");try {object.wait();//使当前线程进入等待(进入Object.wait队列)并释放对象锁} catch (InterruptedException e) {e.printStackTrace();}System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"线程执行结束"); }}};thread.start();Thread thread_2=new Thread(){@Overridepublic void run() {synchronized (object) {System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"进入启动"); try {object.notify();//随机在Object.waitd队列中唤醒一个正在等待该对象锁的线程System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"唤醒一个等待的线程");Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}}};thread_2.start();}
}

执行结果:

1473306408730:Thread-0进入启动
1473306408731:Thread-1进入启动
1473306408731:Thread-1唤醒一个等待的线程
1473306418731:Thread-0线程执行结束

  从时间戳中可以看出 Thread-1 在通知Thread-0 继续执行后,Thread-0 并未立即执行,而是等待Thread-1 释放Object锁,在重新获得Object锁后,才能继续执行。(最后两个时间戳相减刚好是10秒)

二、使用CountDownLatch让唤醒的线程立即执行

在上面的实例中我们实现了线程之间的通信,但线程Thread-0被唤醒后,并没有立即执行而是,等待Thread-1线程执行完毕释放锁后才执行,那我们如何做到让线程被唤醒后立即执行呢?在这里我们可以使用JDK1.5被引入的CountDownLatch类来轻松实现。

package com.jalja.org.thread.demo02;import java.util.concurrent.CountDownLatch;public class CountDownLatchTest {public static void main(String[] args) {final CountDownLatch countDownLatch=new CountDownLatch(2);Thread thread=new Thread(){@Overridepublic void run() {System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"进入启动");try {countDownLatch.await();//使当前线程进入等待(进入Object.wait队列)并释放对象锁} catch (InterruptedException e) {e.printStackTrace();}System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"线程执行结束"); }};thread.start();Thread thread_3=new Thread(){@Overridepublic void run() {System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"进入启动"); try {countDownLatch.countDown();//随机在Object.waitd队列中唤醒一个正在等待该对象锁的线程
                     countDownLatch.countDown();System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"唤醒一个等待的线程");Thread.sleep(10000);System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"线程结束");} catch (InterruptedException e) {e.printStackTrace();}}};thread_3.start();}
}

执行结果:

1500554407368:Thread-0进入启动
1500554407368:Thread-1进入启动
1500554407368:Thread-1唤醒一个等待的线程
1500554407369:Thread-0线程执行结束
1500554417369:Thread-1线程结束

由结果可以看出Thread-0在被唤醒后立即执行了(时间相差1毫秒)在10后,Thread-1 才执行结束。

转载于:https://www.cnblogs.com/jalja/p/5852556.html

java 线程协作 wait(等待)与 notiy(通知)相关推荐

  1. 线程等待通知 linux,Java 线程协作 wait(等待)与 notiy(通知)

    一.wait().notify()和notifyAll() 为了更好的支持多线程之间的协作,JDK提供了三个重要的本地方法 //调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对 ...

  2. java线程协作_java线程系列之三(线程协作)

    上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者问题是一个经典的线程同步以及通信的案例.该问题描述了两个共享固定大小缓冲区的线程,即所谓 ...

  3. Java线程通信之等待/通知

    等待/通知机制 Object类的wait()方法可以使当前线程在该对象上等待.该方法将当前线程置入"预执行队列"中,并且在wait()所在的代码行处停止运行,直到接到通知或被中断为 ...

  4. java线程协作_java 线程间的协作

    [java]代码库import java.util.Vector; /** * 线程间的协作 */ public class WaitNotify { /** * 打印信息的类,是一个线程. */ s ...

  5. java线程唤醒与等待_Java线程的等待与唤醒

    生产者和消费者必须使用同步代码块包裹起来,保证等待和唤醒只能有一个执行,同步使用的锁对象必须保证唯一 Thread中重要方法 void wait() 在其他线程调用此对象的notify()方法或not ...

  6. java线程优先级队列等待_java线程池队列优先级(插队)Demo

    在做线程池操作的时候,突然来个加紧处理时,会很纠结,不知道怎么处理让加紧的线程插队先执行.该Demo使用了自定义线程池,采用优先级阻塞式队列(PriorityBlockingQueue)的方式来处理插 ...

  7. java线程等待_java 中线程等待与通知的实现

    java 中线程等待与通知的实现 前言: 关于等待/通知,要记住的关键点是: 必须从同步环境内调用wait().notify().notifyAll()方法.线程不能调用对象上等待或通知的方法,除非它 ...

  8. java 线程等待10_面试被问10个Java等待、通知、同步问题,直接躺下

    1.什么时候需要Java同步? Java中的同步是一个重要的概念,因为Java是一种多线程语言,其中多个线程并行运行以完成程序执行.在多线程环境中,Java对象的同步变得极为重要,同步在Java中,可 ...

  9. java 线程等待队列_Java多线程学习(五)——等待通知机制

    等待通知机制的实现 方法wait()的作用是使当前线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程放到"预执行队列",并在wait()所在的代码处停止执行 ...

  10. java多线程三之线程协作与通信实例

    多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition. ...

最新文章

  1. 未来,所有的企业级SaaS应用都将依托于容器
  2. 数据库还原失败System.Data.SqlClient.SqlError: 无法执行 BACKUP LOG,因为当前没有数据库备份...
  3. 复选框全选效果,根据单个复选框的选择情况确定全选复选框是否被选
  4. JZOJ 5396. 【NOIP2017提高A组模拟10.6】Blocks
  5. 李沐《动手学深度学习》新增PyTorch和TensorFlow实现,还有中文版
  6. OpenCV applyColorMap函数实现False color伪色彩的实例(附完整代码)
  7. 关于调试windows services的方法
  8. Vue2.0+vuex+H5实现音乐播放及歌曲切换功能的方法及原理解释
  9. 《并行计算的编程模型》一3.5 远程内存访问:put和get
  10. iOS开发sourceTree提交和拉取代码的时候每次输入密码解决
  11. OpenCV --- 实现两幅图像并排合并(ROI)
  12. 【LeetCode】【数组】题号:*189,旋转数组
  13. 市场监管总局通报部分转供电主体不执行国家电价政策案例
  14. [2018.11.03 T3] 单调序列
  15. I2C(smbus pmbus)和SPI分析
  16. php汉字转换拼音,php如何将汉字转换为拼音
  17. Python实现将mp3音频格式转换为wav格式
  18. java 字符串的字节数_在Java中怎么计算字符编码和字符串所占字节数 .
  19. iPhone指环贴:你手机的防盗专家
  20. ARM 微处理器的数据类型

热门文章

  1. SQL Server内部的内存管理
  2. Obsolete属性用法
  3. window.showModalDialog用法
  4. ACL'22 | 使用对比学习增强多标签文本分类中的k近邻机制
  5. 【NLPCC 2021】 First Call For Papers
  6. 【论文解读】一种新的涨分神器!构造code-switching增广数据进行fine-tuning!
  7. 【知识点】长文超详讲解深度学习中你总是掌握不牢的若干知识点
  8. 潜安 | 分享最新最前沿的IT教程
  9. 深度之眼_Week2 编程作业1_梯度下降
  10. Python —os.listdir() 方法