Friday, June 11, 2010

An analysis on producer consumer problem

Producer consumer problem is classical problem solved by multi threading. Multi threading is needed only if we want to make the process efficient. e.g. A thread will start a machine to produce a design and then same thread will execute another machine which will use design produced by first machine to make product. No multi threading here, but this design is not efficient. We are not utilizing machines to their fullest capacity machine 1 is waiting while machine 2 is on work and vice versa.

Now lets modify the design: we can have two threads one will be executing machine 1 and another will execute machine 2. Both will run concurrently. While mc 1 is producing design mc 2 will make final product based on design earlier made by mc1.

class Store{

boolean empty = true;

}

class Producer extends Thread{

public void run(){

while(true){

if(Store.empty){

//pretend as if I am working though I am sleeping
sleep(1000);
Store.empty = false;
}}}}

class Consumer extends Thread{

public void run(){

while(true){
if(!Store.empty){

//I am working see below
sleep(2000);
Store.empty = true;

}}}}

The above technique is known as busy waiting. It has got serious problems e.g. It can consume all the available CPU time(since both thread will be always running and may not be really doing any productive work). Another problem can be if consumer thread priority is more then producer thread it may stop producer thread form producing anything.

To solve above we need to use monitors and wait state. Code added in above snippet to implement monitor/wait is highlighted.

class Store{
boolean empty = true;
}

class Producer extends Thread{

public void run(){

while(true){

syncronize(Store){

if(Store.empty){

//pretend as if I am working though I am sleeping
sleep(1000);
Store.empty = false;
Store.notifyAll();
Store.wait();
}}}}}

class Consumer extends Thread{

public void run(){

while(true){

syncronize(Store){
if(!Store.empty){

//I am working see below
sleep(2000);
Store.empty = true;
Store.notifyAll();
Store.wait();

}}}}