在上一次https://www.cnblogs.com/webor2006/p/12083720.html完成了Condition线程同步的实例,但是还木有对其运行流程进行分析,所以这次对它进行一个细致的分析,并且再对其代码做一些调整加深对其的印象,先回顾一下上次的代码:
public class MyTest2 {
public static void main(String[] args) {
BoundedContainer boundedContainer = new BoundedContainer();
//利用java8的流来产生多个生产者线程
IntStream.range(0, 10).forEach(i -> new Thread(() -> {
try {
boundedContainer.put("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start());
//利用java8的流来产生多个生产者线程
IntStream.range(0, 10).forEach(i -> new Thread(() -> {
try {
boundedContainer.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start());
}
}
class BoundedContainer {
private String[] elements = new String[10];
private Lock lock = new ReentrantLock();
private Condition notEmptyCondition = lock.newCondition();
private Condition notFullCondition = lock.newCondition();
private int elementCount;//elements数组中已有的元素数量
private int putIndex;
private int takeIndex;
public void put(String element) throws InterruptedException {
this.lock.lock();
try {
while (this.elementCount == this.elements.length) {
notFullCondition.await();
}
elements[putIndex] = element;
if (++putIndex == this.elements.length) {
putIndex = 0;
}
++elementCount;
System.out.println("put method: " + Arrays.toString(elements));
notEmptyCondition.signal();
} finally {
this.lock.unlock();
}
}
public String take() throws InterruptedException {
this.lock.lock();
try {
while (0 == this.elementCount) {
notEmptyCondition.await();
}
String element = elements[takeIndex];
elements[takeIndex] = null;
if (++takeIndex == elements.length) {
takeIndex = 0;
}
--elementCount;
System.out.println("take method: " + Arrays.toString(elements));
notFullCondition.signal();
return element;
} finally {
this.lock.unlock();
}
}
}
其运行结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/c228948ed9893811f9ad54c61de10443.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6028dbe11c11b057dabb06e2a8022098.png)
所以在结果的输出上也存在一个先后顺序了,先打印的是存放相关的输出,再打印的取元素,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/2aceb2fa669e1720addf764a6256e555.png)
而从输出的结果可以看到,存放元素的位置和取出元素的位置如预期,都是按着上一次的位置进行的,那如果咱们这样巅倒一下顺序呢?
![](https://i-blog.csdnimg.cn/blog_migrate/dd13cd32af214800df48fb23d327fa53.png)
再运行:
![](https://i-blog.csdnimg.cn/blog_migrate/00dd46f8d7121b12d2beb2f3d127a718.png)
这次的输出就木有这么工整了,原因是由于在还木有元素的情况下先消费肯定会阻塞,所以:
![](https://i-blog.csdnimg.cn/blog_migrate/25903f0b690f02ca5da9771fd67a2b31.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e9621ad7d973e5cc8cfc77f344bf245b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/65ba8459385b4766ef9e301ba4a71d2d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d0047b0e875f12d5ebbc418eab7ad631.png)
接着就不继续细分析了,基本上就是按着上面说的原则进行执行的,好,下面继续来修改一下生产者与消费者的线程数,来对写的程序做做测试:
![](https://i-blog.csdnimg.cn/blog_migrate/d6d1352591969f56267ab9308cf23c3f.png)
嗯,没啥问题,先生产了5个数据,然后再消费了5个,接下来再来修改:
![](https://i-blog.csdnimg.cn/blog_migrate/1b41a88b82e10ce6b969a881920b21f3.png)
结果:
put method: [hello, null, null, null, null, null, null, null, null, null]
put method: [hello, hello, null, null, null, null, null, null, null, null]
put method: [hello, hello, hello, null, null, null, null, null, null, null]
put method: [hello, hello, hello, hello, null, null, null, null, null, null]
put method: [hello, hello, hello, hello, hello, null, null, null, null, null]
put method: [hello, hello, hello, hello, hello, hello, null, null, null, null]
put method: [hello, hello, hello, hello, hello, hello, hello, null, null, null]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, null, null]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, null]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [null, hello, hello, hello, hello, hello, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, null, hello, hello, hello, hello, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, null, hello, hello, hello, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, null, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, null, null, hello, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, null, hello, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, hello, hello, null, hello, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, hello, hello, hello, null, hello, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, hello, hello, hello, hello, null, hello, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, hello, hello, hello, hello, hello, null, hello]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, null]
put method: [hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [null, hello, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [null, null, hello, hello, hello, hello, hello, hello, hello, hello]
take method: [null, null, null, hello, hello, hello, hello, hello, hello, hello]
take method: [null, null, null, null, hello, hello, hello, hello, hello, hello]
take method: [null, null, null, null, null, hello, hello, hello, hello, hello]
take method: [null, null, null, null, null, null, hello, hello, hello, hello]
take method: [null, null, null, null, null, null, null, hello, hello, hello]
take method: [null, null, null, null, null, null, null, null, hello, hello]
take method: [null, null, null, null, null, null, null, null, null, hello]
take method: [null, null, null, null, null, null, null, null, null, null]
Process finished with exit code 0
20个生产者与20个消费者执行完之后,最终肯定是把数组中的元素都给消费掉了,妥妥的。继续来修改程序进行测试:
![](https://i-blog.csdnimg.cn/blog_migrate/7aa96ba25e523e82bf0dbbb3567156f2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/01426b81b0ed4d72729a6ec2b9c7ec2e.png)
那如果反过来呢?
![](https://i-blog.csdnimg.cn/blog_migrate/7e0e2af70119cc295a149a65cd3268b4.png)
运行:
![](https://i-blog.csdnimg.cn/blog_migrate/b99fdd756729560366c90130ac67e92c.png)
以上就是关于Condition这个例子解析,说实话要实现这样一个功能并不是很简单的,但是消化好这个例子对于Condition的理解是非常好的。