一、引言
在java中,对于任意一个java对象,它都拥有一组定义在java.lang.Object上监视器方法,包括wait(),wait(long timeout),notify(),notifyAll(),这些方法配合synchronized关键字一起使用可以实现等待/通知模式。
同样,Condition接口也提供了类似Object监视器的方法,通过与Lock配合来实现等待/通知模式。Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
二、Condition和Object监视器对比
三、实例
public class ConditionTest {
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
System.out.println("我需要等一个信号"+this);
condition.await();
System.out.println("我拿到一个信号"+this);
} catch (Exception e) {
// TODO: handle exception
} finally{
lock.unlock();
}
}
}, "thread1");
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
System.out.println("我拿到了锁");
Thread.sleep(500);
System.out.println("我发出一个信号");
condition.signal();
} catch (Exception e) {
// TODO: handle exception
} finally{
lock.unlock();
}
}
}, "thread2");
thread2.start();
}
}
运行结果:
我需要等一个信号com.luchao.traditionalthread.ConditionTest$1@10bc3c9
我拿到了锁
我发出一个信号
我拿到一个信号com.luchao.traditionalthread.ConditionTest$1@10bc3c9
可以看到,Condition的执行方式,是当在线程1中调用await方法后,线程1将释放锁,并且将自己沉睡,等待唤醒,线程2获取到锁后,开始做事,完毕后,调用Condition的signal方法,唤醒线程1,线程1恢复执行。
以上说明Condition是一个多线程间协调通信的工具类,使得某个,或者某些线程一起等待某个条件(Condition),只有当该条件具备( signal 或者 signalAll方法被带调用)时 ,这些等待线程才会被唤醒,从而重新争夺锁。
Condition与传统线程通信有些类似,它的使用更广,可以将多个线程进行通信,以完成更加复杂的通信。