使用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的线程,使其代码继续执行
    }

}
原文地址:https://www.cnblogs.com/Donnnnnn/p/7234934.html