为什么80%的码农都做不了架构师?>>>   

当一个线程修改了一个对象的值,另外一个线程需要感知到这个变化,并且做出相应的操作时,可以使用Java中的等待/通知机制去实现这个功能。

与等待/通知相关的方法是Java中所有对象都具备的方法,它们被定义在java.lang.Object中。

  1. notify()方法:通知一个在对象上等待的线程,使其从wait()方法中返回,并且返回的前提是该线程获取到了对象的锁。

  2. notifyAll()方法:与notify()不同的是,会通知所有等待在该对象上的线程。

  3. wait()方法:调用该方法的线程会在对象上等待,进入WAITING状态,只有等待另外的线程通知或者被中断才会返回。调用wait()方法后,会释放对象的锁。

  4. wait(long timeout):超时等待一段时间,如果等待指定时间后还没有收到通知就会超时返回,参数单位为毫秒。

  5. wait(long timeout, int nanos):超时等待更加精确的实现方法,可精确到纳秒。

当线程A调用的对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()或者notifyAll()方法,线程A将会收到通知从O的wait()返回,继续执行后续操作。

等待/通知的经典实现方式:

等待方(消费者):

synchronized(obj){while(判断条件不满足){obj.wait();}其它处理逻辑
}

通知方(生产者):

 synchronized(obj){改变条件obj.notifyAll();}

使用等待/超时机制实现一个简单的对象池,模拟多个线程不断地从对象池中取出资源,使用完后归还资源到对象池中,使得其它线程可以继续使用这些资源。

定义资源类:

public class Resource {private String name;public Resource(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

定义对象池:

public class ResourcePool {// 使用双向列表保存所有的资源private LinkedList<Resource> pool = new LinkedList<Resource>();public ResourcePool(int poolSize) {// 初始化pool,将可用的对象放入pool中for (int i = 0; i < poolSize; i++) {pool.add(new Resource("RES_" + i));}}// 获取资源public Resource getResource(long timeout) {long future = System.currentTimeMillis() + timeout;long waitRemain = timeout;synchronized (pool) {// 判断有没有资源,若没有则等待while (pool.isEmpty()) {try {// 在pool对象上等待,此时会释放pool对象的锁pool.wait(waitRemain);} catch (InterruptedException e) {e.printStackTrace();}waitRemain = future - System.currentTimeMillis();if (waitRemain <= 0) {// 若等待超时,则返回nullSystem.out.println(Thread.currentThread().getName() + " get resource time out");return null;}}// 将资源从pool中移除,并返回资源Resource resource = pool.removeFirst();System.out.println(Thread.currentThread().getName() + " get resource: " + resource.getName());return resource;}}// 释放资源public void releaseResource(Resource resource) {if (resource != null) {synchronized (pool) {// 归还资源pool.addLast(resource);System.out.println(Thread.currentThread().getName() + " released resource: " + resource.getName());// 通知所有等待在pool对象上的线程pool.notifyAll();}}}
}

main方法:

    public static void main(String[] args) {// 多个线程从资源池中同步获取资源final ResourcePool resPool = new ResourcePool(5);// 使用闭锁,让所有线程同时开始执行final CountDownLatch startGate = new CountDownLatch(1);for (int i = 0; i < 10; i++) {Thread thread = new Thread(new Runnable() {public void run() {try {// 等待闭锁的计数器为0时,才能继续向下执行startGate.await();} catch (InterruptedException e) {e.printStackTrace();}// 获取资源,5秒超时Resource resource = resPool.getResource(5000);if (resource != null) {try {// 随机等待(1~10秒)若干秒后,再释放资源Random random = new Random();Thread.sleep((random.nextInt(9) + 1) * 1000);} catch (InterruptedException e) {e.printStackTrace();}resPool.releaseResource(resource);}}});thread.setName("Th_" + i);thread.start();}// 闭锁的计数减1,此时值为0,所有线程开始继续执行startGate.countDown();}

控制台输出:

Th_9 get resource: RES_0
Th_7 get resource: RES_1
Th_8 get resource: RES_2
Th_6 get resource: RES_3
Th_3 get resource: RES_4
Th_6 released resource: RES_3
Th_0 get resource: RES_3
Th_7 released resource: RES_1
Th_4 get resource: RES_1
Th_8 released resource: RES_2
Th_2 get resource: RES_2
Th_1 get resource time out
Th_5 get resource time out
Th_0 released resource: RES_3
Th_4 released resource: RES_1
Th_9 released resource: RES_0
Th_2 released resource: RES_2
Th_3 released resource: RES_4

转载于:https://my.oschina.net/lukios/blog/603265

Java中的等待/通知机制(wait/notify)相关推荐

  1. java sleep唤醒_Java中的等待唤醒机制—至少50%的工程师还没掌握!

    Java中的等待唤醒机制-至少50%的工程师还没掌握! 发布时间:2019-12-14 01:53, 浏览次数:222 , 标签: Java 这是一篇走心的填坑笔记,自学Java的几年总是在不断学习新 ...

  2. java 等待_Java并发之等待/通知机制

    1 前言 本篇文章默认大家对synchronized跟ReentrantLock有一定了解. 1.1 先来段代码放松一下 下面一段简单的代码,主要是通过3个线程对count进行累计来进行模拟多线程的场 ...

  3. Java并发编程,Condition的await和signal等待通知机制

    Condition简介 Object类是Java中所有类的父类, 在线程间实现通信的往往会应用到Object的几个方法: wait(),wait(long timeout),wait(long tim ...

  4. Java并发编程(04):线程间通信,等待/通知机制

    本文源码:GitHub·点这里 || GitEE·点这里 一.概念简介 1.线程通信 在操作系统中,线程是个独立的个体,但是在线程执行过程中,如果处理同一个业务逻辑,可能会产生资源争抢,导致并发问题, ...

  5. Java 用“等待-通知”机制优化循环等待

    Java 用"等待-通知"机制优化循环等待 在等待不消息CPU的情况下, 最好的方案应该是: 如果线程要求的条件不满足,则线程阻塞自己,进入等待状态: 当线程要求的条件满足后,通知 ...

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

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

  7. 超强图文|并发编程【等待/通知机制】就是这个feel~

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If ...

  8. 浅析Condition与等待通知机制

    Condition是在java 1.5中才出现的,它用来替代传统的Object的wait().notify()实现线程间的协作,相比使用Object的wait().notify(),使用Conditi ...

  9. 用“等待-通知”机制优化循环等待

    用"等待-通知"机制优化循环等待 前言 完美的就医流程 用 synchronized 实现等待 - 通知机制 小试牛刀:一个更好地资源分配器 尽量使用 notifyAll() 总结 ...

最新文章

  1. rfc6455 WebSockets
  2. CodeForces 1138B暴力+剪枝
  3. 用户态程序阻塞原因_进程阻塞 操作系统某种情况进行进程的阻塞和唤醒操作...
  4. TensorFlow HOWTO 2.2 支持向量回归(软间隔)
  5. 关于Android(Java)创建匿名线程
  6. python语言开发平台_Go+Python双语言混合开发
  7. GB35114 A级过检
  8. Amos中介效应检验
  9. 『危机领导力』告诉我们如何带好团队
  10. css flex实现经典的三栏布局
  11. JS中every()和some()的对比使用丨蓄力计划
  12. Android系统篇(一)——建立Android系统开发环境
  13. 《深入理解JAVA虚拟机》周志明 第三版 - 第二章 JAVA内存区域与内存溢出异常
  14. 拨开迷雾选型数据中台,兼谈这些供应商的商业模式
  15. Hbuilder和HbuilderX连接到夜神模拟机运行
  16. 单闭环调速仿真matlab,利用Matlab仿真平台设计单闭环直流调速系统
  17. 2-9 彩虹瓶 (20 分)
  18. 《顺序表和链表之链表》
  19. 解压专家Oka for Mac(压缩解压软件)中文版
  20. SqlServer双机热备模式下单节点数据库重装后的配置

热门文章

  1. python Counter类
  2. querywrapper or and嵌套_两个经常用的逻辑函数AND函数,OR函数
  3. 网上的python教程值不值得买_Python新人入手线程技术教程,值得收藏
  4. python错误和异常处理怎处理你知道么
  5. 为了上班摸鱼,我用Python开发“BOSS来了”
  6. linux终端运行pytorch,Linux虚拟机测试pytorch运行
  7. CentOS7 自定义登录前后欢迎信息
  8. 教你如何运用python实现简单文件读写函数
  9. 【学习笔记】超简单的多项式除法(含完整证明)
  10. 【分块】#6278. 数列分块入门 2 (区间修改、查询权值c在区间中的排名)