import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
class BoundedBuffer {
private final Queue<String> buffer;
private final int capacity;
public BoundedBuffer(int capacity) {
this.buffer = new LinkedList<>();
this.capacity = capacity;
}
public synchronized boolean put(String message) {
if (buffer.size() == capacity) { // Fail if buffer is full
return false;
}
buffer.add(message);
return true;
}
public synchronized String get() {
if (buffer.isEmpty()) { // Fail if buffer is empty
return null;
}
return buffer.remove();
}
}
class Producer implements Runnable {
private final BoundedBuffer buffer;
private final int id;
private final Random random = new Random();
Producer(BoundedBuffer buffer, int id) {
this.buffer = buffer;
this.id = id;
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
String message = "Message " + i + " from Producer " + id;
while (!buffer.put(message)) { // Wait until successful
Thread.yield();
}
System.out.println("Producer " + id + " added: " + message);
Thread.sleep(random.nextInt(1000));
}
while (!buffer.put("Bye")) { // Wait until successful
Thread.yield();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
private final BoundedBuffer buffer;
private final int id;
private final Random random = new Random();
Consumer(BoundedBuffer buffer, int id) {
this.buffer = buffer;
this.id = id;
}
@Override
public void run() {
try {
while (true) {
String message = null;
while (message == null) {
message = buffer.get();
if (message == null) { // Wait until successful
Thread.yield();
}
}
System.out.println("Consumer " + id + ": " + message);
if ("Bye".equals(message)) {
break;
}
Thread.sleep(random.nextInt(100));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class ProducerConsumerDemo {
private static final int BUFFER_SIZE = 32;
private static final int NUM_PRODUCERS = 2;
private static final int NUM_CONSUMERS = 2;
public static void main(String[] args) throws InterruptedException {
BoundedBuffer buffer = new BoundedBuffer(BUFFER_SIZE);
Thread[] producers = new Thread[NUM_PRODUCERS];
Thread[] consumers = new Thread[NUM_CONSUMERS];
for (int i = 0; i < NUM_PRODUCERS; i++) {
producers[i] = new Thread(new Producer(buffer, i));
producers[i].start();
}
for (int i = 0; i < NUM_CONSUMERS; i++) {
consumers[i] = new Thread(new Consumer(buffer, i));
consumers[i].start();
}
for (Thread producer : producers) {
producer.join();
}
for (Thread consumer : consumers) {
consumer.join();
}
}
}