classic problem: producer and consumer

注意: 1. wait()后 立即放锁, 给其他等待线程使用,当被唤醒,立即从wait()处执行(而不是从方法头重新执行)

          2. notify(), 唤醒其他睡着的线程,不能唤醒自己。

          3. 没有结束的问题用 while(用if, 则可能在错误情况下继续执行)。

public class ProducerConsumer {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
       
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);
       
        new Thread(c).start();
        new Thread(p).start();
        new Thread(p).start();
        new Thread(p).start();
    }
}

class Wotou {
    int id;
   
    Wotou(int id) {
        this.id = id;
    }
   
    public String toString() {
        return "Wotou: " + id;
    }
}

class SyncStack {
    int index = 0;
    //Wotou[] wotou = new Wotou[6];
   
    public synchronized void push(/*Wotou wt,*/ int i) {       
        while (index == 6) {
            System.out.println("----push(Wotou wt):" + index);
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           
        }

        this.notify();
        System.out.println(Thread.currentThread().getName() + "-----producer: " + i );
        //wotou[index] = wt;
        index++;
    }
   
    public synchronized int pop(int i) {
        System.out.println("pop(: " + i);
        while (index == 0) {
            System.out.println("pop():" + index);
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           
        }

        System.out.println("pre this.notify()");
        this.notify();
        System.out.println("end this.notify()");
       
        index--;
        System.out.println("Consumer: " + i);
        return index;
        //return wotou[index];
    }
}

class Producer implements Runnable{
    SyncStack ss;
   
    Producer(SyncStack ss) {
        this.ss = ss;
    }
   
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i=0; i<10; i++){
            Wotou wt = new Wotou(i);
            ss.push(/*wt,*/ i);
                       
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie){
                ie.printStackTrace();
            }
        }   
    }
}

class Consumer implements Runnable{
    SyncStack ss;
   
    Consumer(SyncStack ss) {
        this.ss = ss;
    }
   
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i=0; i<30; i++){
            ss.pop(i);
           
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie){
                ie.printStackTrace();
            }
        }   
    }
}

原文地址:https://www.cnblogs.com/tiechui/p/1893600.html