使用Condition实现等待/通知

2019-04-01  本文已影响0人  迷糊小生

关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。

Condition类具有很好的灵活性,可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性地进行线程通知,在调度线程上更加灵活。

在使用notify()/notifyAll()方法进行通知时,被通知的线程却是由JVM随机选择的。但是使用ReentrantLock结合Condition类是可以实现前面介绍过的“选择性通知”

而synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在它的一个对象身上。线程开始notifyAll()时,需要通知所有WAITING线程,没有选择权,会出现相当大的效率问题。

package other.thread15;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class DemoService {
    private Lock lock = new ReentrantLock();
    private 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();
        }
    }
}
package other.thread15;

public class ThreadA extends Thread {

    private DemoService service;
    
    public ThreadA(DemoService service) {
        this.service = service;
    }
    
    @Override
    public void run() {
        service.await();
    }
}
package other.thread15;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        DemoService service = new DemoService();
        ThreadA threadA = new ThreadA(service);
        threadA.start();
        Thread.sleep(1000);
        service.signal();
    }

}
image.png

成功实现等待/通知模式
Object类中的wait()相当于Condition类中的await()方法。
Object类中的wait(long timeout)相当于Condtion类中的await(long time,TimeUnit unit)方法。
Object类中的notify()方法相当于Condition类中的signal()方法。
Object类中的notifyAll()方法相当于Condition类中的signalAll()方法。

上一篇 下一篇

猜你喜欢

热点阅读