import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.Random;
import java.util.Date;
/**
* Test class which encapsulates a Producer and Consumer (created
* using a simple object hierarchy). Main method starts one producer
* and one consumer using the same mailbox, and they each take and put
* 10 messages (each message is a date).
*
* See if you can explain the output you get from running this; try
* looking at output from different runs. You might also consider
* seeing what happens if you give one of them (producer or consumer)
* longer sleep times than the other.
*/
public class ProducerConsumer {
private static final int size = 10;
private static Random random = new Random();
/**
* User of a mailbox implemented as a BlockingQueue.
*/
private static abstract class MailboxUser<T> {
protected BlockingQueue<T> mailbox;
public MailboxUser(BlockingQueue<T> mailbox) {
this.mailbox = mailbox;
}
}
/**
* Sample Producer which puts 10 dates into the mailbox. Sleeps a
* random amount between 0 and 1 second between each put.
*/
private static class Producer extends MailboxUser<Date>
implements Runnable {
public Producer(BlockingQueue<Date> mailbox) {
super(mailbox);
}
public void run() {
for(int i = 0; i < 10; ++i) {
Date date = new Date();
try {
mailbox.put(date);
System.out.println("Produced " + date);
Thread.sleep(random.nextInt(1000));
} catch(InterruptedException e) {
System.err.println("Producer interrupted");
}
}
}
}
/**
* Sample consumer which takes 10 dates from the mailbox. Sleeps a
* random amount between 0 and 1 second between each take.
*/
private static class Consumer extends MailboxUser<Date>
implements Runnable {
public Consumer(BlockingQueue<Date> mailbox) {
super(mailbox);
}
public void run() {
for(int i = 0; i < 10; ++i) {
try {
Date date = mailbox.take();
System.out.println("Consumed " + date);
Thread.sleep(random.nextInt(1000));
} catch(InterruptedException e) {
System.err.println("Consumer interrupted");
}
}
}
}
public static void main(String[] args) {
ArrayBlockingQueue<Date> mailbox = new ArrayBlockingQueue<Date>(size);
new Thread(new Producer(mailbox)).start();
new Thread(new Consumer(mailbox)).start(); // Same mailbox!!
}
}