Condition提供了线程通讯的一套机制await和signal等线程间进行通讯的方法。。
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
由于线程在调用条件对象的await方法中,首先会释放当前的锁,然后才让自己进入堵塞状态,等待唤醒。
注意,这里是自动进入堵塞。除非被其他线程唤醒或者被中断,否则线程将一直堵塞下去。
此时,其他线程有可能正好拥有这个锁,前面也已经有现成在等待这个锁,所以被唤醒的线程须要进入锁的等待队列中,在前面的线程运行完毕后,才干继续兴许的操作。
线程仅仅有调用条件对象的await方法,才干进入这个条件对象的等待队列中。而线程在调用await方法的前提是线程已经获取了锁,所以线程是在拥有锁的状态下进入条件对象的等待队列的。拥有锁的线程也就是正在执行的线程,是不在锁对象的等待队列中的。
假设没有在锁对象的等待队列中,那么说明事件还没有发生(也就是没有signal方法没有被调用)。所以线程须要堵塞来等待被唤醒。