zoukankan      html  css  js  c++  java
  • 使用Condition配合await()和signal()实现等待/通知

    关键字Synchronizedwait()notify()/notifyAll()结合可以实现“等待/通知”模式,

    Lock类的子ReentrantLock也可以实现同样的功能,但需要借助Condition对象。

    优势:在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,

    线程对象可以注册在指定的Condition中,从而可以有选择性地对指定线程进行通知,

    在调度线程上更加灵活。

    实例如下

    需要下面四个类:

    封装的业务方法类:MyService.java

    线程A类和线程B类:ThreadA.java和ThreadB.java

    运行类:Run.java

    1、MyService.java

    package Condition;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class MyService {
    
        private Lock lock = new ReentrantLock();
        
        public Condition conditionA = lock.newCondition();//创建conditionA对象
        public Condition conditionB = lock.newCondition();//创建conditionB对象
        
        public void awaitA(){
            try{
                lock.lock();//事前加lock,保证线程同步,相当于Synchronized作用
                System.out.println("begin awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
                conditionA.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionA对象
                System.out.println(" end awaitA:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();//最后不忘unlock()
            }
        }
        
        
        public void awaitB(){
            try{
                lock.lock();
                System.out.println("begin awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
                conditionB.await();//进入等待,需要被通知才能继续运行下面代码,绑定conditionB对象
                System.out.println(" end awaitB:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        
        public void signalAll_A(){
            
            try{
                lock.lock();
                System.out.println(" signalAll_A:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
                conditionA.signalAll();//选择性地通知唤醒所有绑定conditionA的对象
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
            
        }
        
    public void signalAll_B(){
            
            try{
                lock.lock();
                System.out.println(" signalAll_B:"+System.currentTimeMillis()+" ThreadName="+Thread.currentThread().getName());
                conditionB.signalAll();//选择性地通知唤醒所有绑定conditionA的对象
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
            
        }
        
        
    }

    2、ThreadA.java

    package Condition;
    
    public class ThreadA extends Thread{
    
        private MyService service;
        
        public ThreadA(MyService service){
            super();
            this.service = service;
        }
        
        @Override
        public void run(){
            service.awaitA();//调用MyService里的awaitA()方法
        }
    }

    3、ThreadB.java

    package Condition;
    
    public class ThreadB extends Thread{
    
        private MyService service;
        
        public ThreadB(MyService service){
            super();
            this.service = service;
        }
        
        @Override
        public void run(){
            service.awaitB();//调用MyService里的awaitB()方法
        }
    }

    4、Run.java

    package Condition;
    
    public class Run {
    
        public static void main(String[] args) {
            
            MyService service = new MyService();
            ThreadA a = new ThreadA(service);
            a.setName("线程A");
            a.start();
            
            ThreadB b = new ThreadB(service);
            b.setName("线程B");
            b.start();
            
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            service.signalAll_A();//通知唤醒绑定ConditionA的线程,使其代码继续执行
        }
    
    }
  • 相关阅读:
    [古城子的房子] 贪心
    [小兔的棋盘] 组合数学
    [Triangle] Fibonacci+二分查找
    [Fibonacci] 矩阵快速幂
    [DP?]素数筛+Lucas定理+费马小定理
    react本地开发关闭eslint检查
    react 不同js文件里公用同一个变量
    js学习笔记
    node内存扩展,前端项目运行时报内存不足的错误
    Gitee码云通过WebHooks实现自动同步代码部署
  • 原文地址:https://www.cnblogs.com/Donnnnnn/p/7234934.html
Copyright © 2011-2022 走看看