以下代码取自的JavaDocCondition:
Condition
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(); } } }
想象一下, 消费者 和 生产者这 两个线程,一个正在使用take,一个put在单个实例上BoundedBuffer。
take
put
BoundedBuffer
假设 消费者 先运行take(),然后锁定,lock然后循环运行notEmpty.await();。
take()
lock
notEmpty.await();
现在, 生产者 如何才能put()通过锁定lock已由 消费者 持有的来进入方法?
put()
我在这里想念什么?是lock线程正在等待其条件之一时“临时释放”吗?锁的重新 进入 到底意味着什么?
双方Lock并synchronized允许一个线程等待的时候,另一个线程可以获得锁放弃锁。要停止等待,线程必须重新获取锁。
Lock
synchronized
注意:它们没有完全释放它,并且如果您进行堆栈跟踪,则可能有多个线程似乎同时持有该锁,但其中最多一个线程将在运行(其余线程将被阻塞)
从Condition.await()
与此条件相关联的锁被原子释放,并且出于线程调度目的,当前线程被禁用,并且处于休眠状态,直到发生以下四种情况之一: 其他一些线程为此条件调用signal()方法,并且当前线程恰好被选择为要唤醒的线程;要么 其他一些线程为此条件调用signalAll()方法。要么 其他一些线程中断当前线程,并支持中断线程挂起;要么 发生“虚假唤醒”。 在所有情况下,在此方法可以返回之前,当前线程必须重新获取与此条件关联的锁。当线程返回时,可以保证保持此锁
与此条件相关联的锁被原子释放,并且出于线程调度目的,当前线程被禁用,并且处于休眠状态,直到发生以下四种情况之一:
在所有情况下,在此方法可以返回之前,当前线程必须重新获取与此条件关联的锁。当线程返回时,可以保证保持此锁