Lock中使用Condition实现等待通知
- Condition类有很好的灵活性,可以实现多路通知功能,一个Lock对象中可以创建多个Condition对象实例,线程对象可以注册在指定的Condition中,进而有选择的进行线程通知,在调度线程上更加灵活
- wait与notify/notifyAll进行等待通知时,被通知的线程是随机的,但是Condition与Lock结合的通知是有选择性的通知
- synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有线程对象都注册在一个Condition对象身上,线程开始notifyAll时,需要通知所有的WAITING线程,没有选择性,会出现很大的效率问题
- public class MyService {
- private Lock lock = new ReentrantLock();
- public Condition condition = lock.newCondition();
- public void await(){
- try {
- lock.lock();
- System.out.println("await时间为"+System.currentTimeMillis());
- condition.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void signal(){
- try {
- lock.lock();
- System.out.println("signal时间为"+System.currentTimeMillis());
- condition.signal();
- } finally {
- lock.unlock();
- }
- }
- }
- public class MyThread extends Thread {
- private MyService service;
- public MyThread(MyService service) {
- this.service = service;
- }
- @Override
- public void run() {
- service.await();
- }
- }
- public class Run {
- public static void main(String[] args) {
- try {
- MyService service = new MyService();
- MyThread mt = new MyThread(service);
- mt.start();
- Thread.sleep(3000);
- service.signal();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-------------------------------------------------------打印输出-------------------------------------------------------
- await时间为1537949157830
- signal时间为1537949160830
Condition类中的await方法相当于Object类中的wait方法
Condition类中的signal/signalAll方法相当于Object类中的notify/notifyAll方法
案例2
- public class MyService {
- private Lock lock = new ReentrantLock();
- public Condition condition = lock.newCondition();
- public void awaitA(){
- try {
- lock.lock();
- System.out.println("begin awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
- condition.await();
- System.out.println("end awaitA时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void awaitB(){
- try {
- lock.lock();
- System.out.println("begin awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
- condition.await();
- System.out.println("end awaitB时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void signalAll(){
- try {
- lock.lock();
- System.out.println("signalAll时间为"+System.currentTimeMillis()+ " ThreadName="+Thread.currentThread().getName());
- condition.signalAll();
- } finally {
- lock.unlock();
- }
- }
- }
线程
- public class ThreadA extends Thread {
- private MyService service;
- public ThreadA(MyService service) {
- this.service = service;
- }
- @Override
- public void run() {
- service.awaitA();
- }
- }
- -------------------------------------------------
- public class ThreadB extends Thread {
- private MyService service;
- public ThreadB(MyService service) {
- this.service = service;
- }
- @Override
- public void run() {
- service.awaitB();
- }
- }
- public class Run {
- public static void main(String[] args) throws InterruptedException {
- MyService service = new MyService();
- ThreadA a = new ThreadA(service);
- a.setName("A");
- ThreadB b = new ThreadB(service);
- b.setName("B");
- a.start();
- b.start();
- Thread.sleep(3000);
- service.signalAll();
- }
- }
-------------------------------------------------------打印输出-------------------------------------------------------
- begin awaitA时间为1537951494924 ThreadName=A
- begin awaitB时间为1537951494925 ThreadName=B
- signalAll时间为1537951497924 ThreadName=main
- end awaitA时间为1537951497924 ThreadName=A
- end awaitB时间为1537951497925 ThreadName=B
线程A和B都被唤醒了
使用多个Condition实现通知部分线程
想要单独唤醒部分线程,就需要使用多个Condition对象,先对线程进行分组,Condition对象可以唤醒部分指定线程,有助于提高程序运行效率
- public class MyService {
- private Lock lock = new ReentrantLock();
- public Condition conditionA = lock.newCondition();
- public Condition conditionB = lock.newCondition();
- public void awaitA(){
- try {
- lock.lock();
- System.out.println("begin awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- conditionA.await();
- System.out.println("--end awaitA时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void awaitB(){
- try {
- lock.lock();
- System.out.println("begin awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- conditionB.await();
- System.out.println("--end awaitB时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void signAll_A(){
- try {
- lock.lock();
- System.out.println("signAll_A时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- conditionA.signalAll();
- } finally {
- lock.unlock();
- }
- }
- public void signAll_B(){
- try {
- lock.lock();
- System.out.println("signAll_B时间为"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
- conditionB.signalAll();
- } finally {
- lock.unlock();
- }
- }
- }
线程
- public class ThreadA extends Thread {
- private MyService service;
- public ThreadA(MyService service) {
- this.service = service;
- }
- @Override
- public void run() {
- service.awaitA();
- }
- }
- -----------------------------------------------
- public class ThreadB extends Thread {
- private MyService service;
- public ThreadB(MyService service) {
- this.service = service;
- }
- @Override
- public void run() {
- service.awaitB();
- }
- }
- public class Run {
- public static void main(String[] args) throws InterruptedException {
- MyService service = new MyService();
- ThreadA a = new ThreadA(service);
- a.setName("A");
- ThreadB b = new ThreadB(service);
- b.setName("B");
- a.start();
- b.start();
- Thread.sleep(3000);
- service.signAll_A();
- }
- }
-------------------------------------------------------打印输出-------------------------------------------------------
- begin awaitA时间为1537952328573 ThreadName=A
- begin awaitB时间为1537952328573 ThreadName=B
- signAll_A时间为1537952331572 ThreadName=main
- --end awaitA时间为1537952331572 ThreadName=A
线程A被唤醒了,但是线程B仍然在等待
Lock中使用Condition实现等待通知的更多相关文章
- 再谈AbstractQueuedSynchronizer:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现
共享模式acquire实现流程 上文我们讲解了AbstractQueuedSynchronizer独占模式的acquire实现流程,本文趁热打铁继续看一下AbstractQueuedSynchroni ...
- Condition实现等待、通知
使用Condition实现等待/通知: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.L ...
- 十六、Condition等待通知
一.简介 我们可以使用syncronized和wait,notify实现等待通知.而syncronized的高级实现Lock,也可以实现等待通知,需要构造Condition的实例对象. JDK文档:h ...
- Lock接口之Condition接口
之前在写显示锁的是后,在显示锁的接口中,提到了new Condition这个方法,这个方法会返回一个Condition对象 简单介绍一下 Condition接口: 任意一个Java对象,都拥有一组监视 ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
- 显式锁(四)Lock的等待通知机制Condition
任意一个Java对象,都拥有一组监视器方法(定义在根类Object上),主要包括:wait( ).wait(long timeout).notify().notifyAll()方法:这些方法与关 ...
- 使用Condition配合await()和signal()实现等待/通知
关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式, Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Con ...
随机推荐
- 排列组合( Lindström–Gessel–Viennot lemma 定理)
链接:https://www.nowcoder.com/acm/contest/139/A来源:牛客网 Monotonic Matrix 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ ...
- 棋盘问题(DFS)& Dungeon Master (BFS)
1棋盘问题 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的 ...
- java 多线程 线程安全及非线程安全的集合对象
一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...
- 解决分布式事务基本思想Base和CPA理论、最终一致性|刚性事务、柔性事务
在学习解决分布式事务基本思路之前,大家要熟悉一些基本解决分布式事务概念名词比如:CAP与Base理论.柔性事务与刚性事务.理解最终一致性思想,JTA+XA.两阶段与三阶段提交等. 如何保证强一致性呢? ...
- java模式-----单例模式
什么是单例设计模式? 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 类结构 ...
- NFA 、DFA 简述
转载请注明出处 https://www.cnblogs.com/majianming/p/11823697.html 目前常见的正则表达引擎总体分为2种,DFA (确定型有穷状态自动机) 和 NFA ...
- commonJs的运行时加载和es6的编译时加载
参考 : https://www.cnblogs.com/jerrypig/p/8145206.html 1.commonJs的运行时加载 2.ES6编译时加载
- Python面向对象 杂篇(后记)
异常处理 什么是异常: 我们在调试程序时,常常会因为各种报错信息导致程序无法运行,异常也是一个对象,用来表示错误.我们可以捕捉异常,并做相应处理,从而增加代码的友好程度. 异常处理: ...
- leetcode上的一些分治算法
53- 思路: 95- 思路
- 集合类不安全之ArrayList
1. 不安全的ArrayList 大家都知道ArrayList线程不安全,怎么个不安全法呢?上代码: public class ContainerNotSafeDemo { public static ...