• Condition类有很好的灵活性,可以实现多路通知功能,一个Lock对象中可以创建多个Condition对象实例,线程对象可以注册在指定的Condition中,进而有选择的进行线程通知,在调度线程上更加灵活
  • wait与notify/notifyAll进行等待通知时,被通知的线程是随机的,但是Condition与Lock结合的通知是有选择性的通知
  • synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有线程对象都注册在一个Condition对象身上,线程开始notifyAll时,需要通知所有的WAITING线程,没有选择性,会出现很大的效率问题
  1. public class MyService {
  2. private Lock lock = new ReentrantLock();
  3. public Condition condition = lock.newCondition();
  4. public void await(){
  5. try {
  6. lock.lock();
  7. System.out.println("await时间为"+System.currentTimeMillis());
  8. condition.await();
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. } finally {
  12. lock.unlock();
  13. }
  14. }
  15.  
  16. public void signal(){
  17. try {
  18. lock.lock();
  19. System.out.println("signal时间为"+System.currentTimeMillis());
  20. condition.signal();
  21. } finally {
  22. lock.unlock();
  23. }
  24. }
  25. }
  1. public class MyThread extends Thread {
  2. private MyService service;
  3.  
  4. public MyThread(MyService service) {
  5. this.service = service;
  6. }
  7.  
  8. @Override
  9. public void run() {
  10. service.await();
  11. }
  12. }
  1. public class Run {
  2. public static void main(String[] args) {
  3. try {
  4. MyService service = new MyService();
  5. MyThread mt = new MyThread(service);
  6. mt.start();
  7. Thread.sleep(3000);
  8. service.signal();
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. }

-------------------------------------------------------打印输出-------------------------------------------------------

  1. await时间为1537949157830
  2. signal时间为1537949160830

Condition类中的await方法相当于Object类中的wait方法

Condition类中的signal/signalAll方法相当于Object类中的notify/notifyAll方法

案例2

  1. public class MyService {
  2. private Lock lock = new ReentrantLock();
  3. public Condition condition = lock.newCondition();
  4.  
  5. public void awaitA(){
  6. try {
  7. lock.lock();
  8. System.out.println("begin awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
  9. condition.await();
  10. System.out.println("end awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. } finally {
  14. lock.unlock();
  15.  
  16. }
  17. }
  18.  
  19. public void awaitB(){
  20. try {
  21. lock.lock();
  22. System.out.println("begin awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
  23. condition.await();
  24. System.out.println("end awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. } finally {
  28. lock.unlock();
  29. }
  30. }
  31.  
  32. public void signalAll(){
  33. try {
  34. lock.lock();
  35. System.out.println("signalAll时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
  36. condition.signalAll();
  37. } finally {
  38. lock.unlock();
  39. }
  40. }
  41. }

线程

  1. public class ThreadA extends Thread {
  2. private MyService service;
  3.  
  4. public ThreadA(MyService service) {
  5. this.service = service;
  6. }
  7.  
  8. @Override
  9. public void run() {
  10. service.awaitA();
  11. }
  12. }
  13. -------------------------------------------------
  14. public class ThreadB extends Thread {
  15. private MyService service;
  16.  
  17. public ThreadB(MyService service) {
  18. this.service = service;
  19. }
  20.  
  21. @Override
  22. public void run() {
  23. service.awaitB();
  24. }
  25. }
  1. public class Run {
  2. public static void main(String[] args) throws InterruptedException {
  3. MyService service = new MyService();
  4. ThreadA a = new ThreadA(service);
  5. a.setName("A");
  6. ThreadB b = new ThreadB(service);
  7. b.setName("B");
  8. a.start();
  9. b.start();
  10. Thread.sleep(3000);
  11. service.signalAll();
  12. }
  13. }

-------------------------------------------------------打印输出-------------------------------------------------------

  1. begin awaitA时间为1537951494924 ThreadName=A
  2. begin awaitB时间为1537951494925 ThreadName=B
  3. signalAll时间为1537951497924 ThreadName=main
  4. end awaitA时间为1537951497924 ThreadName=A
  5. end awaitB时间为1537951497925 ThreadName=B

线程A和B都被唤醒了


使用多个Condition实现通知部分线程

想要单独唤醒部分线程,就需要使用多个Condition对象,先对线程进行分组,Condition对象可以唤醒部分指定线程,有助于提高程序运行效率

  1. public class MyService {
  2. private Lock lock = new ReentrantLock();
  3. public Condition conditionA = lock.newCondition();
  4. public Condition conditionB = lock.newCondition();
  5.  
  6. public void awaitA(){
  7. try {
  8. lock.lock();
  9. System.out.println("begin awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  10. conditionA.await();
  11. System.out.println("--end awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. } finally {
  15. lock.unlock();
  16. }
  17. }
  18.  
  19. public void awaitB(){
  20. try {
  21. lock.lock();
  22. System.out.println("begin awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  23. conditionB.await();
  24. System.out.println("--end awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. } finally {
  28. lock.unlock();
  29. }
  30. }
  31.  
  32. public void signAll_A(){
  33. try {
  34. lock.lock();
  35. System.out.println("signAll_A时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  36. conditionA.signalAll();
  37. } finally {
  38. lock.unlock();
  39. }
  40. }
  41.  
  42. public void signAll_B(){
  43. try {
  44. lock.lock();
  45. System.out.println("signAll_B时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
  46. conditionB.signalAll();
  47. } finally {
  48. lock.unlock();
  49. }
  50. }
  51. }

线程

  1. public class ThreadA extends Thread {
  2. private MyService service;
  3.  
  4. public ThreadA(MyService service) {
  5. this.service = service;
  6. }
  7.  
  8. @Override
  9. public void run() {
  10. service.awaitA();
  11. }
  12. }
  13. -----------------------------------------------
  14. public class ThreadB extends Thread {
  15. private MyService service;
  16.  
  17. public ThreadB(MyService service) {
  18. this.service = service;
  19. }
  20.  
  21. @Override
  22. public void run() {
  23. service.awaitB();
  24. }
  25. }
  1. public class Run {
  2. public static void main(String[] args) throws InterruptedException {
  3. MyService service = new MyService();
  4. ThreadA a = new ThreadA(service);
  5. a.setName("A");
  6. ThreadB b = new ThreadB(service);
  7. b.setName("B");
  8. a.start();
  9. b.start();
  10. Thread.sleep(3000);
  11. service.signAll_A();
  12. }
  13. }

-------------------------------------------------------打印输出-------------------------------------------------------

  1. begin awaitA时间为1537952328573 ThreadName=A
  2. begin awaitB时间为1537952328573 ThreadName=B
  3. signAll_A时间为1537952331572 ThreadName=main
  4. --end awaitA时间为1537952331572 ThreadName=A

线程A被唤醒了,但是线程B仍然在等待

Lock中使用Condition实现等待通知的更多相关文章

  1. 再谈AbstractQueuedSynchronizer:共享模式与基于Condition的等待/通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

  2. 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

  3. Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现

    共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...

  4. Condition实现等待、通知

    使用Condition实现等待/通知: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.L ...

  5. 十六、Condition等待通知

    一.简介 我们可以使用syncronized和wait,notify实现等待通知.而syncronized的高级实现Lock,也可以实现等待通知,需要构造Condition的实例对象. JDK文档:h ...

  6. Lock接口之Condition接口

    之前在写显示锁的是后,在显示锁的接口中,提到了new Condition这个方法,这个方法会返回一个Condition对象 简单介绍一下 Condition接口: 任意一个Java对象,都拥有一组监视 ...

  7. java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)

    一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...

  8. 显式锁(四)Lock的等待通知机制Condition

       任意一个Java对象,都拥有一组监视器方法(定义在根类Object上),主要包括:wait( ).wait(long timeout).notify().notifyAll()方法:这些方法与关 ...

  9. 使用Condition配合await()和signal()实现等待/通知

    关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式, Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Con ...

随机推荐

  1. 排列组合( Lindström–Gessel–Viennot lemma 定理)

    链接:https://www.nowcoder.com/acm/contest/139/A来源:牛客网 Monotonic Matrix 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ ...

  2. 棋盘问题(DFS)& Dungeon Master (BFS)

    1棋盘问题 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的 ...

  3. java 多线程 线程安全及非线程安全的集合对象

    一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...

  4. 解决分布式事务基本思想Base和CPA理论、最终一致性|刚性事务、柔性事务

    在学习解决分布式事务基本思路之前,大家要熟悉一些基本解决分布式事务概念名词比如:CAP与Base理论.柔性事务与刚性事务.理解最终一致性思想,JTA+XA.两阶段与三阶段提交等. 如何保证强一致性呢? ...

  5. java模式-----单例模式

    什么是单例设计模式? 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 类结构 ...

  6. NFA 、DFA 简述

    转载请注明出处 https://www.cnblogs.com/majianming/p/11823697.html 目前常见的正则表达引擎总体分为2种,DFA (确定型有穷状态自动机) 和 NFA ...

  7. commonJs的运行时加载和es6的编译时加载

    参考 : https://www.cnblogs.com/jerrypig/p/8145206.html 1.commonJs的运行时加载 2.ES6编译时加载

  8. Python面向对象 杂篇(后记)

    异常处理 什么是异常:         我们在调试程序时,常常会因为各种报错信息导致程序无法运行,异常也是一个对象,用来表示错误.我们可以捕捉异常,并做相应处理,从而增加代码的友好程度. 异常处理: ...

  9. leetcode上的一些分治算法

    53- 思路: 95- 思路

  10. 集合类不安全之ArrayList

    1. 不安全的ArrayList 大家都知道ArrayList线程不安全,怎么个不安全法呢?上代码: public class ContainerNotSafeDemo { public static ...