//代码1
public class TestProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
producer p = new producer(ss);
customer c = new customer(ss);
new Thread(p).start();
new Thread(c).start();
}
}class WoTou {
int id = 0; WoTou(int id) {
this.id = id;
} public String toString() {
return "WoTou" + id;
}
}class SyncStack {
int index = 0;
WoTou[] ArrWT = new WoTou[6]; public synchronized void push(WoTou wt) {
if (index >= ArrWT.length) {
try {
System.out.println("满了,等待消费");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
ArrWT[index] = wt;
index++;
} public synchronized WoTou pop() {
if (index == 0) {
try {
System.out.println("没WoTou了,等待生产");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
index--;
return ArrWT[index]; }
}class producer implements Runnable {
SyncStack ss = null; producer(SyncStack ss) {
this.ss = ss;
} public void run() {
for (int i = 0; i < 20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}class customer implements Runnable {
SyncStack ss = null; customer(SyncStack ss) {
this.ss = ss;
} public void run() {
for (int i = 0; i < 20; i++) {
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}}/*  //代码2
public class TestProducerConsumer {    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        producer p = new producer(ss);
        customer c = new customer(ss);
        new Thread(p).start();
        new Thread(c).start();
    }
}class WoTou {
    int id = 0;    WoTou(int id) {
        this.id = id;
    }    public String toString() {
        return "WoTou" + id;
    }
}class SyncStack {
    int index = 0;    WoTou[] ArrWT = new WoTou[6];    public synchronized void push(WoTou wt) {
        if (index >= ArrWT.length) {
            try {
                System.out.println("---------------满了,等待消费");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }        }
        ArrWT[index] = wt;
        index++;
        notify();//执行完自己的代码才去唤醒别人,要不别人就会和你抢cpu资源。    }    // 改变这无返回值
    public synchronized void pop() {
        if (index == 0) {
            try {
                System.out.println("没WoTou了,等待生产");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        notify();//虽然我唤醒了那些等待的线程,但线程我还是持有对象的锁!!!
        index--;
        // return ArrWT[index];
        // 改变如下:
        System.out.println("消费了:        " + ArrWT[index]);        
    }
}class producer implements Runnable {
    SyncStack ss = null;    producer(SyncStack ss) {
        this.ss = ss;
    }    public void run() {
        for (int i = 0; i < 20; i++) {
            WoTou wt = new WoTou(i);
            ss.push(wt);
            System.out.println("生产了:" + wt);
            try {
                Thread.sleep(200);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }}class customer implements Runnable {
    SyncStack ss = null;    customer(SyncStack ss) {
        this.ss = ss;
    }    public void run() {
        for (int i = 0; i < 20; i++) {
            // WoTou wt=ss.pop();//锁定了对象
            //执行到下面这句,你已经没有对象的锁!!!
            // System.out.println("消费了: "+wt);
            // 改变如下:
            ss.pop();//锁定了对象
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }    }}
*/看上面两段代码,
第一段运行结果:
生产了:WoTou0
消费了: WoTou0
生产了:WoTou1
生产了:WoTou2
生产了:WoTou3
生产了:WoTou4
消费了: WoTou4
生产了:WoTou5
生产了:WoTou6
生产了:WoTou7
满了,等待消费
消费了: WoTou7
生产了:WoTou8
满了,等待消费
消费了: WoTou8
生产了:WoTou9
满了,等待消费
消费了: WoTou9
生产了:WoTou10
满了,等待消费
消费了: WoTou10
生产了:WoTou11
满了,等待消费
消费了: WoTou11
生产了:WoTou12
满了,等待消费
消费了: WoTou12
生产了:WoTou13
满了,等待消费
生产了:WoTou14
消费了: WoTou13
满了,等待消费
生产了:WoTou15
消费了: WoTou14
满了,等待消费
生产了:WoTou16
消费了: WoTou15
满了,等待消费
消费了: WoTou16
生产了:WoTou17
满了,等待消费
消费了: WoTou17
生产了:WoTou18
满了,等待消费
消费了: WoTou18
生产了:WoTou19
消费了: WoTou19
消费了: WoTou6
消费了: WoTou5
消费了: WoTou3
消费了: WoTou2
消费了: WoTou1
出现了等待消费,接着又生产了,如WoTou15而第二段:
生产了:WoTou0
消费了:        WoTou0
生产了:WoTou1
生产了:WoTou2
生产了:WoTou3
生产了:WoTou4
消费了:        WoTou4
生产了:WoTou5
生产了:WoTou6
生产了:WoTou7
---------------满了,等待消费
消费了:        WoTou7
生产了:WoTou8
---------------满了,等待消费
消费了:        WoTou8
生产了:WoTou9
---------------满了,等待消费
消费了:        WoTou9
生产了:WoTou10
---------------满了,等待消费
消费了:        WoTou10
生产了:WoTou11
---------------满了,等待消费
消费了:        WoTou11
生产了:WoTou12
---------------满了,等待消费
消费了:        WoTou12
生产了:WoTou13
---------------满了,等待消费
消费了:        WoTou13
生产了:WoTou14
---------------满了,等待消费
消费了:        WoTou14
生产了:WoTou15
---------------满了,等待消费
消费了:        WoTou15
生产了:WoTou16
---------------满了,等待消费
消费了:        WoTou16
生产了:WoTou17
---------------满了,等待消费
消费了:        WoTou17
生产了:WoTou18
---------------满了,等待消费
消费了:        WoTou18
生产了:WoTou19
消费了:        WoTou19
消费了:        WoTou6
消费了:        WoTou5
消费了:        WoTou3
消费了:        WoTou2
消费了:        WoTou1
就没问题谁能解释下  希望大家能讲解下notify方法。

解决方案 »

  1.   

    notify 好比抽奖,抽到谁得到那把锁谁就会得到锁
    notifyAll 好比把锁往下一扔,谁抢到谁就得到锁
      

  2.   


    汗,打个字都打错!notify 好比把等线的线程都放到抽奖箱中,JVM 抽到谁谁就会得到锁
    notifyAll 好比通知等待的线程我要扔锁了,然后往下一扔,谁抢到谁就得到锁
      

  3.   

    照这么说,那么没啥区别啊?   是不是notify是通知锁定在同一对象上的线程,而notifyall是通知所有的等待线程呢?
      

  4.   

    代码1中会出现满了,等待消费
    生产了:WoTou15而代码2中就不会有这个问题,又是怎么回事呢?我看逻辑上没问题啊
      

  5.   

    http://blog.csdn.net/lazy_p/archive/2010/06/02/5642657.aspx
    希望能给楼主有所帮助,呵呵!
      

  6.   

    消费了: WoTou13
    满了,等待消费
    生产了:WoTou15
    消费了: WoTou14
    这个地方是应该先输出  消费了: WoTou14
    然后再输出            生产了:WoTou15 是吗?
    输出 满了,等待消费之后,  producer线程进入waited blocked状态,customer线程抢到时间片执行ss.push()方法,然后两个线程都处于可运行状态,所以两个打印语句争抢时间片,很有可能消费抢到生产之前执行了。所以最好把这两条打印语句放在锁定的方法里,就跟代码二似的,就不会乱了
      

  7.   


    嗯,我把
    new Thread(p).start();
    new Thread(c).start();
    换成
    new Thread(c).start();
    new Thread(p).start();
    由于 
    ss.push(wt);
    System.out.println("生产了:" + wt);
    ss.push(wt)后释放了锁,所以应该会出现问题运行出现了
    没WoTou了,等待生产
    消费了:        WoTou0
    但是还有个小问题,其他线程没有在wait(), 我怎么还是可以调用notify啊?