package lockcommu;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class SyncTest {
  public static void main(String args[]) {
    Stack stack1 = new Stack("stack1");
    Producer producer1 = new Producer(stack1,"producer1");
    Consumer consumer1 = new Consumer(stack1,"consumer1");
    Consumer consumer2 = new Consumer(stack1,"consumer2");
  }
}

/**  生产者线程  */
class Producer extends Thread {
  private Stack theStack;

  public Producer (Stack s,String name) {
    super(name);
    theStack = s;
    start();  //启动自身生产者线程
  }

  public void run() {
    String goods;
    Lock stackLock=theStack.getLock();
    for (int i = 0; i < 200; i++) {
      stackLock.lock();
      try{
        goods="goods"+(theStack.getPoint()+1);
        theStack.push(goods);
      }finally{stackLock.unlock();}

      System.out.println(getName()+ ": push " + goods +" to "+theStack.getName());
      sleep(100);
    }
  }

  public void sleep(int m){ 
    try{super.sleep(m);}catch(Exception e){e.printStackTrace();}
  }
}

/**  消费者线程 */
class Consumer extends Thread {
  private Stack theStack;

  public Consumer (Stack s,String name) {
    super(name);
    theStack = s;  
    start();  //启动自身消费者线程
  }

  public void run() {
    String goods;
    for (int i=0; i < 200; i++) {
      goods = theStack.pop();
      System.out.println(getName() + ": pop " + goods +" from "+theStack.getName());
      yield();
    }
  }
}

/**  堆栈  */
class Stack {
  private String name;
  private String[] buffer=new String[100];
  int point=-1;
  private final Lock stackLock;
  private Condition condition;

  public Stack(String name){
    this.name=name;
    stackLock=new ReentrantLock();
    condition=stackLock.newCondition();
  }
  public String getName(){return name;}
  public Lock getLock(){return stackLock;}

  public int getPoint(){
    stackLock.lock();
    try{
      return point;
    }finally{
      stackLock.unlock();
    }
  }

  public String pop() {
    stackLock.lock();
    try{
      condition.signalAll();

      while(point==-1){
        System.out.println(Thread.currentThread().getName()+": wait");
        condition.await();
      }

      String goods = buffer[point];
      buffer[point]=null;
      Thread.yield();
      point--;

      return goods;
    }catch(InterruptedException e){
      throw new RuntimeException(e);
    }finally{
      stackLock.unlock();
    }
  }

  public void push(String goods) {  
    stackLock.lock();
    try{
      condition.signalAll();

      while(point==buffer.length-1){
        System.out.println(Thread.currentThread().getName()+": wait");
        condition.await();
      }
      point++;
      Thread.yield();
      buffer[point]=goods;
    }catch(InterruptedException e){
      throw new RuntimeException(e);
    }finally{
      stackLock.unlock();
    }
  }
}



/****************************************************
 * 作者：孙卫琴                                     *
 * 来源：<<Java面向对象编程>>                       *
 * 技术支持网址：www.javathinker.net                *
 ***************************************************/

 


