# Producer-Consumer Semaphore Implementation

I have implemented a Producer-Consumer by Semaphore implementation.

Thanks.

package ProducerConsumer.Semaphore;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreMain {

public static void main(String args[]){

int capacity = 50;

Semaphore semaphoreProducer = new Semaphore(1);
Semaphore semaphoreConsumer = new Semaphore(0);

Producer producer = new Producer(arrayList, capacity, semaphoreProducer, semaphoreConsumer);
Consumer consumer = new Consumer(arrayList, capacity, semaphoreProducer, semaphoreConsumer);

es.submit(t1);
es.submit(t2);

es.shutdown();

}
}


Producer.java

package ProducerConsumer.Semaphore;

import java.util.List;
import java.util.concurrent.Semaphore;

public class Producer implements Runnable {

Semaphore semaphoreProducer;
Semaphore semaphoreConsumer;
int capacity;

public Producer(List linkedList, int capacity, Semaphore semaphoreProducer, Semaphore semaphoreConsumer){
this.capacity = capacity;
this.semaphoreProducer = semaphoreProducer;
this.semaphoreConsumer = semaphoreConsumer;
}

@Override
public void run() {

for (int i=0;i<50;i++){

try {
semaphoreProducer.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphoreConsumer.release();

}

}
}


Consumer.java

package ProducerConsumer.Semaphore;

import java.util.List;
import java.util.concurrent.Semaphore;

public class Consumer implements Runnable{

Semaphore semaphoreProducer;
Semaphore semaphoreConsumer;

public Consumer(List linkedList, int capacity, Semaphore semaphoreProducer, Semaphore semaphoreConsumer){
this.semaphoreProducer = semaphoreProducer;
this.semaphoreConsumer = semaphoreConsumer;
}

@Override
public void run() {

while(true){

try {
semaphoreConsumer.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphoreProducer.release();

}

}
}


# Capacity

You don't use capacity, yet you pass it into both your Producer/Consumer classes. Superficially, it looks like you should be passing the capacity in when creating your Producer semaphore. This would allow 'capacity' items to be put into your list. At the moment, you're restricting it to only putting a single item into the list, then reading it back out again.

As it stands, your program works, however, it only works because you have a single consumer and producer. The way you're using the semaphores means that either a consumer can be running, or the producer can be running, they can't both be running at the same time. As a consequence, only one thread is working with the list. If you start supporting more than one producer/consumer however you'll have the potential for having more threads using the collection concurrently... in which case you should consider alternate protection or using a concurrent collection, I'd suggest one of the Queues.

# Naming

List<Integer> arrayList = new LinkedList<>();

This is obviously subjective, but I'm also not a fan of semaphoreProducer... I can't help but expect it to be something that produces semaphores. producerSemaphore works better for me, but as I said...very subjective.
Your Consumer thread doesn't have a way to exit, it just keeps on running. Consider adding some way of notifying the consumer that it's time to shutdown so that the thread can be exited cleanly without you needing to force it to terminate. This will become more important if your consumer starts doing some processing that takes a while that you don't want to exit in the middle of...