Condition的基本使用如下:
* Condition是个接口,基本的方法就是await()和signal()方法;
* Condition依赖于Lock接口,生成一个Condition的基本代码是lock.newCondition()
* 调用Condition的await()和signal()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以
* 和Object.wait()方法一样,每次调用Condition的await()方法的时候,当前线程就自动释放了对当前锁的拥有权
测试的逻辑设计
// 这段程序的目的是测试先put()后take()的操作,
// 1. 我将ConditionDemo的大小设置成5,同时在每次进入notFull和notEmpty的await()的时候打印一下表示当前线程正在等待;
// 2. 先开启10个线程做put()操作,预计有5个线程可以完成,另外5个会进入等待
// 3. 主线程sleep10秒中,然后启动10个线程做take()操作;
// 这个时候,首先第一个take()必然成功完成,在这之前等待的5个put()线程都不会被唤醒, 接下来的事情就不好说了;
// 剩下的5个put()线程和9个take()线程中的任何一个都可能会被jvm调度;
// 比如可能出现
// a. 开始take()的时候,有5个连续的take()线程完成操作; 然后又进入put()和take()交替的情况
// b. 第一个take()之后,立刻会有一个put()线程被notFull().signal()唤醒; 然后继续有take()和put()交替的情况;
//
// 其中take()线程也可能进入notEmpty.await()操作;
// 但是任何时候,未完成的take()线程始终>=未完成的put()线程, 这个也是很自然的;
// 1. 我将ConditionDemo的大小设置成5,同时在每次进入notFull和notEmpty的await()的时候打印一下表示当前线程正在等待;
// 2. 先开启10个线程做take()操作,由于开始ConditionDemo里面没有东西,所以10个线程全部调用await进入等待
// 3. 主线程sleep10秒中,然后启动10个线程做put()操作;
// 在第一个put()完成之后,接下来应该会有部分put()线程和take()线程先后完成;
// 理论上,
// a. 任何一个元素的put()都会发生在take()之前;
// b. 如果X表示某个操作成功的次数,在X(put)-X(take)<5的时候,put线程不会进入等待状态