在Java中为生产者/消费者模式创建同步缓冲区
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在Java中为生产者/消费者模式创建同步缓冲区,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2589字,纯文字阅读大概需要4分钟。
内容图文
![在Java中为生产者/消费者模式创建同步缓冲区](/upload/InfoBanner/zyjiaocheng/817/41dad444294f4101a0b621636367d37a.jpg)
我为生产者/消费者模式实现了一个缓冲区,然而,消费者似乎永远不会获得锁定,因此发生了Starvation.我无法确定为什么会发生这种情况,因为put()和take()似乎都正确释放了锁…
我知道有BlockingQueue和其他很好的实现,但我想用wait()和notify()作为练习来实现它.
public class ProducerConsumerRaw {
public static void main(String[] args) {
IntBuffer buffer = new IntBuffer(8);
ConsumerRaw consumer = new ConsumerRaw(buffer);
ProducerRaw producer = new ProducerRaw(buffer);
Thread t1 = new Thread(consumer);
Thread t2 = new Thread(producer);
t1.start();
t2.start();
}
}
class ConsumerRaw implements Runnable{
private final IntBuffer buffer;
public ConsumerRaw(IntBuffer b){
buffer = b;
}
public void run() {
while(!buffer.isEmpty()) {
int i = buffer.take();
System.out.println("Consumer reads "+i); // this print may not be in the order
}
}
}
class ProducerRaw implements Runnable{
private final IntBuffer buffer;
ProducerRaw(IntBuffer b) {
this.buffer = b;
}
public void run(){
for (int i = 0; i < 20; i++) {
int n = (int) (Math.random()*100);
buffer.put(n);
System.out.println("Producer puts "+n);
}
}
}
class IntBuffer{
private final int[] storage;
private volatile int end;
private volatile int start;
public IntBuffer(int size) {
this.storage = new int[size];
end = 0;
start = 0;
}
public void put(int n) { // puts add the END
synchronized(storage) {
boolean full = (start == (end+storage.length+1)%storage.length);
while(full){ // queue is full
try {
storage.notifyAll();
storage.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.storage[end] = n;
end = incrementMod(end);
storage.notifyAll();
}
}
public int take(){
synchronized(storage) {
while (end == start) { // empty queue
try {
storage.notifyAll(); // notify waiting producers
storage.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int index = start;
start = incrementMod(start);
storage.notifyAll(); // notify waiting producers
return this.storage[index];
}
}
private int incrementMod(int index) {
synchronized (storage) {
if (index == storage.length-1) return 0;
else return index+1;
}
}
public boolean isEmpty(){
synchronized (storage) {
return (start == end);
}
}
}
解决方法:
在你的put方法中至少有一个问题:
boolean full = (start == (end+storage.length+1)%storage.length);
while(full){ // queue is full
// Code that doesn't change full
}
如果full被初始化为true,那么你如何期望循环结束呢?
另一个问题是这个循环,在消费者中:
while(!buffer.isEmpty()) {
int i = buffer.take();
System.out.println("Consumer reads "+i);
}
你假设生产者永远不会让缓冲区变空 – 如果消费者在生产者之前开始,它将立即停止.
相反,您想要某种方式告诉缓冲区您已停止生成.消费者应该继续服用,直到队列为空并且不再接收任何数据.
内容总结
以上是互联网集市为您收集整理的在Java中为生产者/消费者模式创建同步缓冲区全部内容,希望文章能够帮你解决在Java中为生产者/消费者模式创建同步缓冲区所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。