class StackImpl { private Object[] stackArray; private volatile int topOfStack; StackImpl (int capacity) { stackArray = new Object[capacity]; topOfStack = -1; } public synchronized Object pop() { System.out.println(Thread.currentThread() + ": popping"); while (isEmpty()) try { System.out.println(Thread.currentThread() + ": waiting to pop"); wait(); // (1) } catch (InterruptedException e) { } Object obj = stackArray[topOfStack]; stackArray[topOfStack--] = null; System.out.println(Thread.currentThread() + ": notifying after pop"); notify(); // (2) return obj; } public synchronized void push(Object element) { System.out.println(Thread.currentThread() + ": pushing"); while (isFull()) try { System.out.println(Thread.currentThread() + ": waiting to push"); wait(); // (3) } catch (InterruptedException e) { } stackArray[++topOfStack] = element; System.out.println(Thread.currentThread() + ": notifying after push"); notify(); // (4) } public boolean isFull() { return topOfStack >= stackArray.length -1; } public boolean isEmpty() { return topOfStack < 0; } } abstract class StackUser extends Thread { // (5) Stack user protected StackImpl stack; // (6) StackUser(String threadName, StackImpl stack) { super(threadName); this.stack = stack; System.out.println(this); setDaemon(true); // (7) Daemon thread start(); // (8) Start this thread. } } class StackPopper extends StackUser { // (9) Popper StackPopper(String threadName, StackImpl stack) { super(threadName, stack); } public void run() { while (true) stack.pop(); } } class StackPusher extends StackUser { // (10) Pusher StackPusher(String threadName, StackImpl stack) { super(threadName, stack); } public void run() { while (true) stack.push(new Integer(1)); } } public class WaitAndNotifyClient { public static void main(String[] args) throws InterruptedException { // (11) StackImpl stack = new StackImpl(5); new StackPusher("A", stack); new StackPusher("B", stack); new StackPopper("C", stack); System.out.println("Main Thread sleeping."); Thread.sleep(1000); System.out.println("Exit from Main Thread."); } }
Possible output from the program:
Thread[A,5,main] Thread[B,5,main] Thread[C,5,main] Main Thread sleeping. ... Thread[A,5,main]: pushing Thread[A,5,main]: waiting to push Thread[B,5,main]: pushing Thread[B,5,main]: waiting to push Thread[C,5,main]: popping Thread[C,5,main]: notifying after pop Thread[A,5,main]: notifying after push Thread[A,5,main]: pushing Thread[A,5,main]: waiting to push Thread[B,5,main]: waiting to push Thread[C,5,main]: popping Thread[C,5,main]: notifying after pop Thread[A,5,main]: notifying after push ... Thread[B,5,main]: notifying after push ... Exit from Main Thread. ...
No comments:
Post a Comment