关键字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();
}
}
成功实现等待/通知模式
Object类中的wait()相当于Condition类中的await()方法。
Object类中的wait(long timeout)相当于Condtion类中的await(long time,TimeUnit unit)方法。
Object类中的notify()方法相当于Condition类中的signal()方法。
Object类中的notifyAll()方法相当于Condition类中的signalAll()方法。