0

I made the following producer consumer problem with blocking queue with capacity 1. So that producer can produce only one item but running the code producer can produce 2 items and consumer can consume even though queue is empty.

please help in solving this weird behavior as per me this wrong behavior. Producer should block if queue is empty.

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;
        }
    }
}

On running the code it gives below output

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 []
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
torres
  • 1
  • 1
  • 2
  • Hint: class names start UpperCase (so, study java coding styleguides). – GhostCat Aug 29 '16 at 18:22
  • 3
    `System.out.println` may not behave as you are expecting in a multithreaded environment. – bradimus Aug 29 '16 at 18:24
  • My doubt is that since blocking queue size is 1 so produces produces an item and consumer consumes . but if you see the output for case i=2 ;before producer producing it as blocking is printing null consumer is consuming it Thread-0producing 2 [] //producer started producing 2 Thread-1consuming [] //Consumer started consuming Thread-1consumed 2 [] // consumer consumed 2 ideally it should wait Thread-0produced 2 [2] // after consuming 2 producer produces 2. – torres Sep 01 '16 at 18:36
  • @bradimus My doubt is that since blocking queue size is 1 so produces produces an item and consumer consumes . but if you see the output for case i=2 ;before producer producing it as blocking is printing null consumer is consuming it Thread-0producing 2 [] //producer started producing 2 Thread-1consuming [] //Consumer started consuming Thread-1consumed 2 [] // consumer consumed 2 ideally it should wait Thread-0produced 2 [2] // after consuming 2 producer produces 2. – torres Sep 01 '16 at 18:38

1 Answers1

0

you are inserting value of i in blocking queue.

initially value of i is 1 When producer produce one item and put in blocking queue. then consumer consume this item then queue is empty. now again producer run and produce an item and put this item in blocking queue this time item is 2 (value of i) because blocking queue capacity is one so it can not insert more value until queue is empty . now consumer consume an item this time item is 2 (element inside blocking queue) this continue until i <=4.

I think your code is correct .

Abhishek
  • 379
  • 1
  • 8
  • My doubt is that since blocking queue size is 1 so produces produces an item and consumer consumes . but if you see the output for case i=2 ;before producer producing it as blocking is printing null consumer is consuming it Thread-0producing 2 [] //producer started producing 2 Thread-1consuming [] //Consumer started consuming Thread-1consumed 2 [] // consumer consumed 2 ideally it should wait Thread-0produced 2 [2] // after consuming 2 producer produces 2. – torres Sep 01 '16 at 18:37