Name : Muhammad Hassam
Roll no : 037
Section : BSSE-5A
Demonstrate the use of semaphores & mutex locks, by using standard
counting semaphores for empty and full, and a mutex lock, rather
than a binary semaphore, to represent a mutex.
The producer and consumer running as separate threads will move
items to and from a buffer that is synchronized with the empty, full,
and mutex structures.
Code:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class BoundedBuffer {
private final int BUFFER_SIZE;
private Queue<Integer> buffer;
private Semaphore empty;
private Semaphore full;
private Lock mutex;
private int producedCount;
private int consumedCount;
public BoundedBuffer(int size){
this.BUFFER_SIZE = size;
[Link] = new LinkedList<>();
[Link] = new Semaphore(BUFFER_SIZE);
[Link] = new Semaphore(0);
[Link] = new ReentrantLock();
[Link] = 0;
[Link] = 0;
}
public void insert(int item, int producerId) throws InterruptedException{
[Link]();
[Link]();
try{
[Link](item);
producedCount++;
[Link]("Producer " + producerId + ": Produced item " + item
+
" | Buffer size: " + [Link]() +
" | Total produced: " + producedCount);
[Link](" Buffer: " + buffer);
}finally {
[Link]();
[Link]();
}
}
public int remove(int consumerId) throws InterruptedException{
[Link]();
int item = -1;
[Link]();
try{
if(![Link]()){
item = [Link]();
consumedCount++;
[Link]("Consumer " + consumerId + ": Consumed item " +
item +
" | Buffer size: " + [Link]() +
" | Total consumed: " + consumedCount);
[Link](" Buffer: " + buffer);
}
}finally {
[Link]();
[Link]();
}
return item;
}
public int getProducedCount() {
[Link]();
try {
return producedCount;
} finally {
[Link]();
}
}
public int getConsumedCount() {
[Link]();
try {
return consumedCount;
} finally {
[Link]();
}
}
public int getBufferSize() {
[Link]();
try {
return [Link]();
} finally {
[Link]();
}
}
public int getCapacity() {
return BUFFER_SIZE;
}
// Producer
import [Link];
public class Producer implements Runnable{
private int producerId;
private BoundedBuffer buffer;
private int maxItems;
private Random random;
public Producer(int producerId, BoundedBuffer buffer, int maxItems) {
[Link] = producerId;
[Link] = buffer;
[Link] = maxItems;
[Link] = new Random();
}
@Override
public void run(){
try{
while ([Link]() < maxItems){
int item = [Link](100) + 1;
[Link]([Link](400) + 100);
if([Link]() >= maxItems){
break;
}
[Link](item,producerId);
}
}catch (InterruptedException e){
[Link]().interrupt();
[Link]("Producer " + producerId + ": Interrupted");
}finally {
[Link]("Producer " + producerId + ": Finished");
}
}
}
//Consumer
import [Link];
public class Consumer implements Runnable{
private int consumerId;
private BoundedBuffer buffer;
private int maxItems;
private Random random;
public Consumer(int consumerId, BoundedBuffer buffer, int maxItems) {
[Link] = consumerId;
[Link] = buffer;
[Link] = maxItems;
[Link] = new Random();
}
@Override
public void run(){
try{
while ([Link]() < maxItems){
if([Link]() >= maxItems){
break;
}
int item = [Link](consumerId);
[Link]([Link](600) + 100);
}
}catch (InterruptedException e){
[Link]().interrupt();
[Link]("Consumer " + consumerId + ": Interrupted");
}finally {
[Link]("Consumer " + consumerId + ": Finished");
}
}
}
//Main
public class Main {
public static void main(String[] args) {
final int BUFFER_SIZE = 5;
final int MAX_ITEMS = 10;
final int NUM_PRODUCERS = 2;
final int NUM_CONSUMERS = 2;
BoundedBuffer buffer = new BoundedBuffer(BUFFER_SIZE);
Thread[] producers = new Thread[NUM_PRODUCERS];
for (int i = 0; i < NUM_PRODUCERS; i++) {
producers[i] = new Thread(new Producer(i + 1, buffer, MAX_ITEMS),
"Producer-" + (i + 1));
producers[i].start();
}
Thread[] consumers = new Thread[NUM_CONSUMERS];
for (int i = 0; i < NUM_CONSUMERS; i++) {
consumers[i] = new Thread(new Consumer(i + 1, buffer, MAX_ITEMS),
"Consumer-" + (i + 1));
consumers[i].start();
}
try {
for (Thread producer : producers) {
[Link]();
}
for (Thread consumer : consumers) {
[Link]();
}
displayStats(buffer);
} catch (InterruptedException e) {
[Link]("Main thread interrupted");
[Link]();
}
}
private static void displayStats(BoundedBuffer buffer) {
[Link](" Total Produced: " + [Link]());
[Link](" Total Consumed: " + [Link]());
[Link](" Remaining in Buffer: " + [Link]());
[Link](" Buffer Capacity: " + [Link]());
}
}
Output: