0

Я сделал следующую проблему с производителем с блокировкой очереди с емкостью 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 [] 
+0

Подсказка: имена классов начинаются с UpperCase (так, изучите java-кодирование стилейгидов). – GhostCat

+3

'System.out.println' может не работать так, как вы ожидаете, в многопоточной среде. – bradimus

+0

Я сомневаюсь, что, поскольку размер очереди блокировки равен 1, то производит производит элемент и потребитель потребляет. но если вы видите выход для случая i = 2, перед тем, как производитель произведет его как блокирование, печатает нуль, потребитель потребляет его Thread-0producing 2 [] // производитель начал производить 2 Thread-1consuming [] // Потребитель начал потреблять Thread-1consumed 2 [] // потребитель потреблял 2 в идеале, он должен был ждать Thread-0produced 2 [2] // после потребления 2 производителя производит 2. – torres

ответ

0

вы вставляете значение I в блокирующем очереди.

Первоначальное значение i равно 1 Когда производитель производит один элемент и помещается в очередь блокировки. то потребитель потребляет этот элемент, тогда очередь пуста. теперь снова запускается производитель и создает элемент и помещает этот элемент в блокирующую очередь, этот элемент времени равен 2 (значение i), так как блокировка очереди - одна, поэтому она не может вставить больше значения, пока очередь не будет пустой. теперь потребитель потребляет элемент, на этот раз элемент 2 (элемент внутри очереди блокировки), это продолжается до i < = 4.

Я думаю, что ваш код правильный.

+0

Я сомневаюсь, что, поскольку размер очереди блокировки равен 1, то производит производит элемент и потребитель потребляет. но если вы видите выход для случая i = 2, перед тем, как производитель произведет его как блокирование, печатает нуль, потребитель потребляет его Thread-0producing 2 [] // производитель начал производить 2 Thread-1consuming [] // Потребитель начал потреблять Thread-1consumed 2 [] // потребляемый потребитель 2 идеально должен ждать Thread-0produced 2 [2] // после потребления 2 производителя производит 2. – torres