Kode Kode - 4 months ago 16
Java Question

How to consume in Producer-Consumer using Semphores?

I am trying out the Producer-Consumer problem using Semaphore. The program looks fine to me except for one place.

public class ProducerConsumerWithSemaphores
{
private final ArrayList<Integer> list = new ArrayList<>(5);
private final Semaphore semaphoreProducer = new Semaphore(1);
private final Semaphore semaphoreConsumer = new Semaphore(0);

private void produce() throws InterruptedException
{
for(int i = 0;i< 5;i++)
{
semaphoreProducer.acquire();
list.add(i);
System.out.println("Produced: " + i);
semaphoreConsumer.release();
}
}

private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
{
semaphoreConsumer.acquire();
System.out.println("Consumer: " + list.remove(list.size()-1));
semaphoreProducer.release();
Thread.sleep(100);
}
}

public static void main(String[] args)
{
final ProducerConsumerWithSemaphores obj = new ProducerConsumerWithSemaphores();

new Thread(new Runnable()
{
@Override
public void run()
{
try
{
obj.produce();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();

new Thread(new Runnable()
{
@Override
public void run()
{
try
{
obj.consumer();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
}
}


Is it okay to check the list if it is not empty before acquiring the semaphore? Will this cause any problem in multithreaded environment?

Answer
private void consumer() throws InterruptedException
{
    while (!list.isEmpty())    /// This line is where I have the doubt

The problem is, if consumer runs faster than producer, your consumer quit immediately, then you have no consumer!!

The correct example looks like, Producer–consumer problem#Using semaphores. I believe your intention is not to use true as endless loop because you want Producer/Consumer to quit when job is done. If that's your intention, you can set a totalCount to end the loop. Or a boolean flag which will be set by producer after putItemIntoBuffer when producer put the last one. The flag must be protected as well as the buffer.

Will this cause any problem in multithreaded environment?

Your critical section (your list) is not protected . Usually we use 3 semaphores. The 3rd one is used as a mutex to protect the buffer.