【Java 深入学习】一个经典问题 - 消费者和生产者问题 - 下
初版代码示例
PS:
public void run()// throws Exception //错误 Runnable 里没有异常处理
t2.start();//错误 因为无法判断是先进还是先出,如果先进则没错 但如果先出 则现在栈中没有元素 导致数组下标越界
结果:
报数组溢出错误
解释:
我们观察程序,发现我们创造了一个栈 有两个方法 分别是 pop()与 push() 出栈与入栈,这个栈其实就是 糖果池 而糖果池的最大容量就是 这个栈的最大值 6
之后我们创建了生产者与消费者且他们都实现了 Runnable 接口与 run 方法,生产者会在 run 方法中 push()一个元素 也就是增加一个糖果,消费者会在 run 方法中 pop()一个元素 也就是减少一个糖果。
最后我们创建了生产线程与消费线程,我们令生产线程的生产速率小于消费线程,最终会发现当糖果池为 0 后消费线程还在消费,导致溢出错误。
解决方案代码示例
PS:
while(cnt==data.length)//注意://这里用 while 是为了保证 栈为满而暂停,然后下一次如果再满还是再这个循环里 保证再暂停,//如果改成 if 则只能暂停一次 下一次从暂停的那个位置继续走
//但如果是同步过以后则可以用 if,因为如果满 则暂停(wait)生产线程 同时解除霸占,转换到//消费线程 进行消费操作 并锁住消费线程对象 导致一定会运行完消费操作 使得栈不为满 之后//唤醒生产操作 并结束消费程序 解锁,之后再竞争
// 但这种 while 与 if 都可以用的情况 仅在 只有两个相互依赖的线程 的条件下成立,我们可以想一想 如果我们现在来一个毫不相干的线程 c c 运行完后也// 会唤醒某个线程 这样不满足条件的线程依旧可能被唤醒 并且因为是 if 所以直接跳出 if 进行生产操作 导致错误
//使用 wait 会解锁,sleep 则不会
this.notify();//唤醒其他某一个暂停的线程 对于这个例子 就是唤醒消费线程
this.notify();//唤醒其他某一个暂停的线程 对于这个例子 就是唤醒生产线程
public void run()// throws Exception //错误 Runnable 里没有异常处理
Thread.sleep(200);//这种是生产比较慢 消费快
Thread.sleep(200);//这种是消费比较慢 生产快
结果:
生产线程正在生产第 1 个产品,该产品是:a
消费线程正在消费第 1 个产品,该产品是:a
生产线程正在生产第 1 个产品,该产品是:b
消费线程正在消费第 1 个产品,该产品是:b
生产线程正在生产第 1 个产品,该产品是:c
消费线程正在消费第 1 个产品,该产品是:c
生产线程正在生产第 1 个产品,该产品是:d
消费线程正在消费第 1 个产品,该产品是:d
生产线程正在生产第 1 个产品,该产品是:e
消费线程正在消费第 1 个产品,该产品是:e
生产线程正在生产第 1 个产品,该产品是:f
消费线程正在消费第 1 个产品,该产品是:f
生产线程正在生产第 1 个产品,该产品是:g
消费线程正在消费第 1 个产品,该产品是:g
生产线程正在生产第 1 个产品,该产品是:h
消费线程正在消费第 1 个产品,该产品是:h
生产线程正在生产第 1 个产品,该产品是:i
消费线程正在消费第 1 个产品,该产品是:i
生产线程正在生产第 1 个产品,该产品是:j
消费线程正在消费第 1 个产品,该产品是:j
生产线程正在生产第 1 个产品,该产品是:k
消费线程正在消费第 1 个产品,该产品是:k
生产线程正在生产第 1 个产品,该产品是:l
消费线程正在消费第 1 个产品,该产品是:l
生产线程正在生产第 1 个产品,该产品是:m
消费线程正在消费第 1 个产品,该产品是:m
生产线程正在生产第 1 个产品,该产品是:n
消费线程正在消费第 1 个产品,该产品是:n
生产线程正在生产第 1 个产品,该产品是:o
消费线程正在消费第 1 个产品,该产品是:o
生产线程正在生产第 1 个产品,该产品是:p
消费线程正在消费第 1 个产品,该产品是:p
生产线程正在生产第 1 个产品,该产品是:q
消费线程正在消费第 1 个产品,该产品是:q
生产线程正在生产第 1 个产品,该产品是:r
消费线程正在消费第 1 个产品,该产品是:r
生产线程正在生产第 1 个产品,该产品是:s
消费线程正在消费第 1 个产品,该产品是:s
生产线程正在生产第 1 个产品,该产品是:t
消费线程正在消费第 1 个产品,该产品是:t
解释:
因为消费线程比较快,所以现在的情况就是生产一个立马就被消费了
版权声明: 本文为 InfoQ 作者【Geek_65222d】的原创文章。
原文链接:【http://xie.infoq.cn/article/67fcbb562c5429c462a2c84c6】。未经作者许可,禁止转载。
评论