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

线程同步问题不知到哪里出错了
Java code

class Storage
{
    public int i = 0;
}

class Counter implements Runnable
{
    private Storage storage;
    
    public Counter(Storage s)
    {
        storage = s;
    }
    
    public void run()
    {
        try
        {
            Thread.sleep(100);
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
        for(int i = 0; i != 100; ++i)
        {
            synchronized(storage)
            {
                storage.i = i;
                System.out.println("counter: " +storage.i);
                storage.notify();
            }
        }
    }
}

class Printer implements Runnable
{
    private Storage storage;
    public Printer(Storage s)
    {
        storage = s;
    }
    
    public void run()
    {
        for(int i = 0; i != 100; ++i)
        {
            synchronized(storage)
            {
                try
                {
                    storage.wait();
                }
                catch(Exception e)
                {
                    System.out.println(e);
                }
                System.out.println("printer: " +storage.i);
            }
        }
    }
}

public class TestThread
{
    public static void main(String[] argv)
    {
        Storage s = new Storage();
        Thread counter = new Thread(new Counter(s));
        Thread printer = new Thread(new Printer(s));
        printer.start();
        counter.start();
    }
}



打印结果是:
counter: 0
.
.
.
counter: 97
counter: 98
counter: 99
printer: 99
然后就卡在这里了。
代码有问题吗?没发现,求高手们指点下



------解决方案--------------------
Printer 里的storage 调用了Object的wait();调用之后没有被唤醒,需要加上storage.notify();才可以继续执行。 
void wait() 
Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
//api 文档解释,没有被唤醒,就一直睡在那,肯定不执行了。到99的时候其实第一个进程就执行完了。
------解决方案--------------------
Java code


class Storage 
{
    public int i = 0;
    boolean isWaiting=false;//是否已在等待
}

class Counter implements Runnable
{
    private Storage storage;
    
    public Counter(Storage s)
    {
        storage = s;
    }
    
    public void run()
    {
        for(int i = 0; i != 100; ++i)
        {
          
            synchronized(storage)
            {
                //没有消费者等待,则不创建数据
                if(!storage.isWaiting){
                    i--;
                    continue;
                }
                storage.i=i;
                System.out.println("counter: " +storage.i);
                storage.notify();//通知消费者去取该数据
                try {
                    storage.wait();//等待消费者去使用数据
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Printer implements Runnable
{
    private Storage storage;
    public Printer(Storage s)
    {
        storage = s;
    }
    
    public void run()
    {
        for(int i = 0; i != 100; ++i)
        {
           
            synchronized(storage)
            {
                try
                {
                    storage.isWaiting=true;//必须要先等待
                    storage.wait();//等待生产者去创建数据
                }
                catch(Exception e)
                {
                    System.out.println(e);
                }
                System.out.println("printer: " +storage.i);
                storage.notify();//通知生产者去创建数据
            }
        }
    }
}

public class TestThread
{
    public static void main(String[] argv)
    {
        Storage s = new Storage();
        Thread counter = new Thread(new Counter(s));
        Thread printer = new Thread(new Printer(s));
        printer.start();
        counter.start();
    }
}