日期:2014-05-20  浏览次数:20634 次

新人关于多线程生产消费的问题

public class ProduceConsume
{}
/*
这是一个生产消费的程序中模拟栈的类,设定的是生产20个取出20个,想问下关于notify的问题
*/
class syncstack
{
int cnt = 0;
char[] data = new char[6];
char ch;

public synchronized void push(char ch)
{
while (cnt == data.length)
{
try
{
this.wait();
}
catch(Exception e)
{
}
this.notify();//把notify放在while循环里后只生产6个取出6个,然后两个线程都停滞了,为什么?
    }
    //this.notify();  
    
    data[cnt] = ch;
    cnt++;
    System.out.printf("生产了%c\n", ch);
    System.out.printf("当前容器共有%d个物品\n", cnt);
    


public synchronized void pop()
{
char ch;
while(cnt ==0)
{
try
{
this.wait();
}
catch(Exception e)
{
}
            this.notify(); //把notify放在while循环里后只生产6个取出6个,然后两个线程都停滞了,为什么?
        }
//this.notify();
ch = data[cnt-1];
--cnt;
System.out.printf("消费了物品%c\n", ch);
System.out.printf("当前还剩下%d个物品\n", cnt);
}
}
class produce implements Runnable{}
class consume implements Runnable{}

------解决方案--------------------
public synchronized void push(char ch) 
    {
        while (cnt == data.length)
        {
         System.out.println("1111111");
            try
            {
             System.out.println("3333333");
             this.wait();
               
            }
            catch(Exception e)
            {
             e.printStackTrace();
            }
           
            this.notify();
            System.out.println("call thread consume");
        }
        //this.notify();
         
        data[cnt] = ch;
        cnt++;
        System.out.printf("生产了%c\n", ch);
        System.out.printf("当前容器共有%d个物品\n", cnt);
         
    } 
  
this.wait()调用后,后面的this.notify()还能执行吗?

线程都已经停止了,当然this.notify()是不能够执行到的,结果就是你没办法唤醒线程了, 解决的办法是将this.notify()放到this.wait()之前去,这样就ok了

改后代码
package thread.mypackage;

public class ProduceConsume
{
    public static void main(String[] args)
    {
        syncstack ss = new syncstack();
        produce p = new produce(ss);
        consume c = new consume(ss);
         
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(c);
         
        t1.start();
        t2.start();
    }   
}
 
class syncstack
{
    static int cnt = 0;
    char[] data = new char[6];
    char ch;
     
    public synchronized void push(char ch) 
    {
        while (cnt == data.length)
        {
         //System.out.println("1111111");
            try
            {