Я сделал следующую проблему с производителем с блокировкой очереди с емкостью 1. Так что производитель может производить только один элемент, но запуск производителя кода может производить 2 элемента, и потребитель может потреблять, хотя очередь пуста.Очередь блокировки массива с емкостью 1 неправильное поведение производителя-потребителя
, пожалуйста, помогите решить это странное поведение в соответствии с этим неправильным поведением. Производитель должен блокировать, если очередь пуста.
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 []
Подсказка: имена классов начинаются с UpperCase (так, изучите java-кодирование стилейгидов). – GhostCat
'System.out.println' может не работать так, как вы ожидаете, в многопоточной среде. – bradimus
Я сомневаюсь, что, поскольку размер очереди блокировки равен 1, то производит производит элемент и потребитель потребляет. но если вы видите выход для случая i = 2, перед тем, как производитель произведет его как блокирование, печатает нуль, потребитель потребляет его Thread-0producing 2 [] // производитель начал производить 2 Thread-1consuming [] // Потребитель начал потреблять Thread-1consumed 2 [] // потребитель потреблял 2 в идеале, он должен был ждать Thread-0produced 2 [2] // после потребления 2 производителя производит 2. – torres