1

I was trying to solve the Single Producer & Consumer problem, As per the problem statement from wikipedia https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem Production and Consumption should happen endlessly such that the producer should not add to queue when it is full and consumer should not consume when it is empty

I have solved it using Thread.sleep and a double check using continue in the infinite while loop and created two threads one producer and consumer, It seems to run fine without breaking, but I did not find this solution recommended elsewhere, I have attached the code

My question is will this solution break or does it have any performance hit when compared to locking or using produce/consume count,

Code:

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Random;

class Buffer{

    static final int MAX_SIZE=5;
    static Deque<Integer> bufferQueue=new ArrayDeque<>();


    static int produce(){
        int value=new Random().nextInt(10);
        bufferQueue.offer(value);
        return value;

    }

    static int consume(){
        return bufferQueue.poll();
    }
}
public class BufferTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //Producer Thread
        new Thread(
                ()->{
                    while(true){

                        if(Buffer.bufferQueue.size()==Buffer.MAX_SIZE){
                            try {
                                System.out.println("Buffer Full");
                                Thread.sleep(2000);
                                continue;    //Double Check
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        }
                        System.out.println("Produced "+Buffer.produce());
                    }
                },"Producer"
                ).start();

        //Consumer Thread
        new Thread(
                ()->{
                    while(true){

                        if(Buffer.bufferQueue.size()==0){
                            try {
                                System.out.println("Buffer Empty");
                                Thread.sleep(2000);
                                continue;   //Double check
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        System.out.println("Consumed "+Buffer.consume());
                    }
                },"Consumer"
                ).start();
    }

}
  • "does it have any performance hit" Yes, you're sleeping for 2 seconds whenever the list is empty or full. – Andy Turner Sep 29 '16 at 11:11
  • Putting `continue` after the sleep isn't really double-checking, and it's definitely not locking. – Andy Turner Sep 29 '16 at 11:13
  • @Andy: Thanks for the reply, the thread sleeps only when the queue is full or empty, which is what is done in a blocking queue if I am not wrong and how do you assert that using continue is not double checking, when the producer sleeps when queue is full and wakes up the continue statement forces it to start the loop again and check again if the queue is full right? – Mallikarjun Pasunkili Sep 30 '16 at 05:57
  • 1
    "which is what is done in a blocking queue if I am not wrong" You are wrong. For example, "sleep" does not occur in the code for [`ArrayBlockingQueue`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/ArrayBlockingQueue.java/), [`DelayQueue`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/DelayQueue.java/), [`LinkedBlockingQueue`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/LinkedBlockingQueue.java/), etc. – Andy Turner Sep 30 '16 at 07:36
  • 1
    And it isn't "double" checking because you're simply checking. If you actually look at what [double-checked locking](https://en.wikipedia.org/wiki/Double-checked_locking) is, you'll see that you actually check the condition twice per block (not simply looping), and, significantly *you may acquire a lock*. Would you consider it "triple checking" if the you slept twice before producing/consuming? – Andy Turner Sep 30 '16 at 07:40

0 Answers0