java线程生产者消费者有关问题

java线程生产者消费者问题package threadlearning高手指教一下啊public class ProducerConsumer {public

java线程生产者消费者问题
package threadlearning;

高手指教一下啊

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(p).start();
new Thread(c).start();
}

}

class WoTou
{
private int id;

public WoTou(int id)
{
this.id = id;
}

public String toString()
{
return "wotou的数量 : "+id; 
}
}

class Producer implements Runnable 
{
SyncStack ss = null;
Producer(SyncStack ss) 
{
this.ss = ss;
}

public void run() 
{
for(int i=0; i<10; i++) 
{
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
//try {
//Thread.sleep(5000);
//} catch (InterruptedException e) {
//e.printStackTrace();
//}
}
}
}

class Consumer implements Runnable 
{
SyncStack ss = null;
Consumer(SyncStack ss) 
{
this.ss = ss;
}

public void run() 
{
for(int i=0; i<10; i++) 
{
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SyncStack
{
WoTou [] arrWt = new WoTou[6];
int index = 0;

public synchronized void push(WoTou wt)
{
while(index >= 6)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

this.notify();
arrWt[index]= wt;
index++;
}

public synchronized WoTou pop()
{
while(index==0)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

this.notify();
index--;
return arrWt[index];
}

}


输出结果
消费了: wotou的数量 : 0
生产了:wotou的数量 : 0
生产了:wotou的数量 : 1
生产了:wotou的数量 : 2
生产了:wotou的数量 : 3
生产了:wotou的数量 : 4
生产了:wotou的数量 : 5
生产了:wotou的数量 : 6
生产了:wotou的数量 : 7--------------怎么会超出容量呢?????????????
消费了: wotou的数量 : 6
生产了:wotou的数量 : 8
消费了: wotou的数量 : 7
消费了: wotou的数量 : 8
生产了:wotou的数量 : 9
消费了: wotou的数量 : 9
消费了: wotou的数量 : 5
消费了: wotou的数量 : 4
消费了: wotou的数量 : 3
消费了: wotou的数量 : 2
消费了: wotou的数量 : 1

































[解决办法]
SyncStack这个的容量并没有超出


for(int i=0; i <10; i++) 

WoTou wt = new WoTou(i); 
ss.push(wt); 
System.out.println("生产了:" + wt); 

楼主new 10个WoTou,new一个就push一个,等到SyncStack满了,就wait(),此时程序并没有停止,等到SyncStack不满的时候,还会继续new WoTou,直到for循环结束!!


[解决办法]

Java code
public synchronized void push(WoTou wt) { while(index >= 6) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); arrWt[index]= wt; index++; } public synchronized WoTou pop() { while(index==0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); index--; return arrWt[index]; } }
------解决方案--------------------


消费者notify以后还是在互斥代码段里啊,生产者还是要等index--的吧
[解决办法]
消费了: wotou的数量 : 0
生产了:wotou的数量 : 0
生产了:wotou的数量 : 1
生产了:wotou的数量 : 2
生产了:wotou的数量 : 3
生产了:wotou的数量 : 4
生产了:wotou的数量 : 5
生产了:wotou的数量 : 6
生产了:wotou的数量 : 7--------------怎么会超出容量呢????????????? 

从这可以看出,现在共生产了8个wotou,消费了1个wotou,index>=6的时候wait了,怎么会出现7个呢?

WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt); 
i=7的时候,ss.put(wt7);index=6;线程wait().
这时消费者
WoTou wt = ss.pop();//执行到这的时候,pop()方法,index--;生产者线程执行,打印了 "生产了:wotou的数量 : 7",然后才
System.out.println("消费了: " + wt); 

第一行打印 "消费了: wotou的数量 : 0",也是一样的道理,消费者执行pop(),index=0,wait(),
WoTou wt = new WoTou(i);
ss.push(wt);//index++了,消费者线程执行,打印了第一行.
然后才
System.out.println("生产了:" + wt); 

程序简单改一改就看出来了.

Java code
public void run() {        for (int i = 0; i < 10; i++) {            try {                Thread.sleep(200);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("消费: 先消费,再生产");            WoTou wt = ss.pop();            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }执行结果:生产:wotou ID : 0生产:wotou ID : 1生产:wotou ID : 2生产:wotou ID : 3生产:wotou ID : 4生产:wotou ID : 5//生产到6个,就开始消费.消费: 先消费,再生产生产:wotou ID : 6消费: 先消费,再生产生产:wotou ID : 7消费: 先消费,再生产生产:wotou ID : 8消费: 先消费,再生产生产:wotou ID : 9消费: 先消费,再生产消费: 先消费,再生产消费: 先消费,再生产消费: 先消费,再生产消费: 先消费,再生产消费: 先消费,再生产