本帖最后由 hzy2121211 于 2010-03-02 22:10:50 编辑

解决方案 »

  1.   

    package Thread;public class TwoThread {
    public static void main(String[] args) {
    Queue q=new Queue ();//new出一个q:后面的两个线程都是用的同一个q,保证一个put一个get
    Producer p=new Producer (q);//让new出的p去往q里面put
    Customer c=new Customer (q);//让new出的c从q中get
    p.start();//p和q开始的顺序并不报错
    c.start();

    }
    }
    class Producer extends Thread
    {
    Queue q;
    public Producer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的put方法
    }
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    q.put(i);//此处只是让q去put  10次
    System.out.println("Producer put "+i);//并且输出本次放的是第几杯
    }
    }
    }
    class Customer extends Thread
    {
    Queue q;
    public Customer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的get方法
    }
    @Override
    public void run() {
    while (true) {//死循环:只要q里面有,就去get
    //get方法有返回值,返回值就是producer所put的数量
    //此处也不需要去考虑是第几杯
    //在Queue中的value解决可这一问题:
    //put中的I赋给value,get方法有返回值就value的值
    System.out.println("Customer get "+q.get());
    //如果循环完了,就跳出循环,否则线程不会自己结束
    if (q.value==9) {
    break;
    }
    }

    }
    }
    class Queue
    {
    int value;
    boolean bFull=false;
    public synchronized void put (int i)//在producer中的put方法中就是将其I传进来
    {
    if (!bFull) {//条件为真(如果没满,就倒水)
    value=i;//给value赋值,现在有几杯水
    bFull=true;//满了
    notify();//唤醒其他线程(让customer去get)
    }
    try {
    wait();//告诉customer去get后自己等待customer的get结束
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    public synchronized int get()
    {
    if (!bFull) {//如果没满就等待,如果满了就不进    **这就是为什么main里面谁先开始不报错的原因**
    //get和put方法中的if条件判断起到了至关重要的作用
    try {
    wait();
    } catch (InterruptedException e) {

    e.printStackTrace();
    }
    }
    bFull =false;//赋值为没满
    notify();//唤醒producer去put
    return value;//get的返回值就是put的时候给value赋的值
    }
    }
      

  2.   

    public class ProducerConsumer { static SyncStack ss = new SyncStack(); public static void main(String[] args) {
    // TODO Auto-generated method stub
    Producer p = new Producer(ss);
    Consumer c = new Consumer(ss);
    Thread t1 = new Thread(p);
    Thread t2 = new Thread(c);
    t1.start();
    t2.start();
    }
    }// 这个是生产出来的产品WoTou(窝头)
    class WoTou {
    int id; WoTou(int id) {
    this.id = id;
    } public String toString() {
    return "WoTou" + id;
    }
    }// 这个是存放的产品的容器,有点模拟栈的形式
    class SyncStack {
    static int index = 0; // 标记当前产品的位置,或者产品数量
    WoTou[] wtArr = new WoTou[20]; // 容器容量是20 // 把产品放进容器的方法
    public synchronized void produce(WoTou w) {
    if (index == 20) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } else {
    this.notify();
    }
    System.out.println("产: " + index);
    wtArr[index++] = w;
    ; // 生产完一个产品后,标记往上移动
    } // 把产品从容器拿出来的办法
    public synchronized WoTou consume() {
    if (index == 0) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } else {
    this.notify();
    }
    System.out.println("取: " + index);
     // 取出来后,标记往下移
    return wtArr[--index];
    }
    }// 生产者,就是把产品放进容器
    class Producer implements Runnable { SyncStack ss; Producer(SyncStack ss) {
    this.ss = ss;
    } public void run() {
    int i = 0; // 为了能让生产不断生产,我添加了这个while
    while (true) {
    ss.produce(new WoTou(i));
    // System.out.println("生产 " + ss.wtArr[ss.index] + ", 还有 "
    // + ss.index + " 个产品");
    i++;
    }
    }
    }// 消费者,把产品从容器拿出来
    class Consumer implements Runnable {
    SyncStack ss; Consumer(SyncStack ss) {
    this.ss = ss;
    } public void run() {
    while (true) { // 为了能让生产不断生产,我添加了这个while
    ss.consume();
    // System.out.println("消费 " + ss.wtArr[ss.index] + ",还有" + ss.index
    // + "个产品");
    }
    }
    }
      

  3.   

    把上面的产和取的方法用下面替换就是你想要的了:
    public synchronized void produce(WoTou w) {
    if (index == 20) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } else {
    this.notify();
    }
    System.out.println("产: " + wtArr[index] + "还有: " + index + "个");
    wtArr[index++] = w;
    ; // 生产完一个产品后,标记往上移动
    } // 把产品从容器拿出来的办法
    public synchronized WoTou consume() {
    if (index == 0) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } else {
    this.notify();
    }
    // System.out.println("取: " + index);
    System.out.println("取: " + wtArr[index - 1] + "还有: " + (index - 1) + "个");
     // 取出来后,标记往下移
    return wtArr[--index];
    }