package com.interview.design.questions; import java.util.ArrayDeque; import java.util.Queue; import java.util.Random; /** * Created with IntelliJ IDEA. * User: stefanie * Date: 7/25/14 * Time: 1:36 PM */ public class DZ17_ProducerConsumerProblem { static class Message { int time; String message; Message(int time, String message) { this.time = time; this.message = message; } } static class MessageQueue<T> { Queue<T> queue = new ArrayDeque<T>(); public void add(T element) { queue.add(element); synchronized (this){ System.out.println("Add element to the queue, queue size is " + queue.size()); this.notifyAll(); } } public T get() { return queue.poll(); } public boolean isEmpty() { return queue.isEmpty(); } } static class Producer implements Runnable { MessageQueue<Message> queue; Random random = new Random(); int id; public Producer(int id, MessageQueue<Message> queue) { this.id = id; this.queue = queue; } @Override public void run() { System.out.printf("PRODUCER-%d IS ON\n", this.id); while (true) { int time = random.nextInt(5); String message = "A task need " + time + " seconds"; Message m = new Message(time, message); System.out.printf("PRODUCER-%d: generate a message %s\n ", this.id, m.message); queue.add(m); try { Thread.currentThread().sleep(2 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void start(){ Thread thread = new Thread(this); thread.start(); } } static class Consumer implements Runnable { MessageQueue<Message> queue; int id; public Consumer(int id, MessageQueue<Message> queue) { this.id = id; this.queue = queue; } @Override public void run() { System.out.println("CONSUMER IS ON"); while (true) { Message m = null; while(m == null){ synchronized (queue) { if (queue.isEmpty()) { try { //System.out.printf("CONSUMER-%d: waiting for message\n", this.id); queue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { m = queue.get(); } } } System.out.printf("CONSUMER-%d: handling %s\n", this.id, m.message); try { Thread.currentThread().sleep(m.time * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("CONSUMER-%d: finish %s\n", this.id, m.message); } } public void start(){ Thread thread = new Thread(this); thread.start(); } } public static void main(String[] args) { MessageQueue<Message> queue = new MessageQueue<>(); for(int i = 0; i < 10; i++){ if(i % 2 == 0) new Producer(i/2+1, queue).start(); new Consumer(i+1, queue).start(); } } }