我使用容量为1的阻塞队列产生了以下生产者消费者问题。因此,生产者只能生成一个项目,但运行代码生成器可以生成2个项目,即使队列为空,消费者也可以使用。
请帮助解决这种奇怪的行为,因为我这种错误的行为。如果队列为空,生产者应该阻止。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
class prodconsimpl{
public static void main(String[] args){
BlockingQueue<Integer> arr=new ArrayBlockingQueue<Integer>(1);
producer pd=new producer(arr);
consumer cs=new consumer(arr);
Thread t1=new Thread(pd);
Thread t2=new Thread(cs);
t1.start();
t2.start();
}
}
class producer implements Runnable{
BlockingQueue<Integer> arr;
producer(BlockingQueue<Integer> arr){
this.arr=arr;
}
public void run(){
for(int i=1;i<=4;i++){
try{
System.out.println(Thread.currentThread().getName() +"producing "+i+" "+arr);
arr.put(i);
// System.out.println(Thread.currentThread().getName() +" "+arr);
System.out.println(Thread.currentThread().getName() +"produced "+i+" "+arr);
}
catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
class consumer implements Runnable{
BlockingQueue<Integer> arr;
consumer(BlockingQueue<Integer> arr){
this.arr=arr;
}
public void run(){
while(true){
int i=0;;
try{
System.out.println(Thread.currentThread().getName() +"consuming "+" "+ arr);
//System.out.println(Thread.currentThread().getName() +" "+arr);
i=arr.take();
//System.out.println(Thread.currentThread().getName() +" "+arr);
System.out.println(Thread.currentThread().getName() +"consumed " + i+" "+arr);
}
catch(InterruptedException ex){
ex.printStackTrace();
}
if(i==4)
break;
}
}
}
在运行代码时,它提供了以下输出
Thread-1consuming []
Thread-0producing 1 []
Thread-0produced 1 [1]
Thread-1consumed 1 []
Thread-0producing 2 []
Thread-1consuming []
Thread-1consumed 2 []
Thread-0produced 2 [2]
Thread-1consuming []
Thread-0producing 3 []
Thread-0produced 3 [3]
Thread-0producing 4 []
Thread-0produced 4 [4]
Thread-1consumed 3 []
Thread-1consuming [4]
Thread-1consumed 4 []
答案 0 :(得分:0)
您正在阻塞队列中插入i的值。
最初i的值为1当生产者生成一个项目并放入阻塞队列时。然后消费者使用此项目,然后队列为空。现在再次生成器运行并生成一个项目,并将此项目放在阻塞队列中,此时项目为2(i的值),因为阻塞队列容量为1,因此在队列为空之前不能插入更多值。现在消费者消耗一个项目,这次项目是2(阻塞队列中的元素),这一直持续到i <= 4。
我认为你的代码是正确的。