notify()无法在Runnable中工作

时间:2013-07-31 14:46:25

标签: java multithreading

为什么我无法在此代码中收到reader的通知:

public class ThreadMain {
    public Thread reader;
    private class SerialReader implements Runnable 
        {
        public void run() 
            {
                try
                {
                Thread.sleep(3000);

                synchronized(this)
                    {
                    System.out.println("notifying");
                    notify();
                    }
                Thread.sleep(3000);
                } catch (Exception e){}
            }
        }

    ThreadMain()
    {
    reader = (new Thread (new SerialReader())   );
    }

    public static void main(String [] args) {
    ThreadMain d= new ThreadMain();    
    d.reader.start();
        synchronized(d)
        {
            try
            {    
            d.wait();
            System.out.println("got notify");
            } catch (Exception e) { System.out.println(e); }

        }

    }
}

我在输出

中只有notifying

3 个答案:

答案 0 :(得分:2)

notifywait不使用相同的监视器,因此他们无法相互“交谈”。

一个简单的解决方法是将阅读器用作主屏幕中的显示器:

synchronized (d.reader) {
    try {
        d.reader.wait();
        System.out.println("got notify");
    } catch (Exception e) {
        System.out.println(e);
    }
}

答案 1 :(得分:0)

您的wait()notify()应位于同一监视器下。目前notifySerialReader监视thiswait监视dThreadMain

顺便说一句建议使用notifyAll()代替notify()

答案 2 :(得分:0)

您的代码中存在两个问题。

正如其他人所说。您需要使用相同的锁来使用通知和等待。您正在使用不同的对象进行等待和通知

即使您使用正确的监视器/锁定,您的代码还有另一个问题。问题称为错过通知,即您的SerialReader线程可以在Mainthread执行其wait()方法之前完成,这将导致Mainthread的无限睡眠

解决上述问题的方法是使用锁存器。尝试CountDownLatch见下文

import java.util.concurrent.CountDownLatch;

公共类MyClass {

CountDownLatch latch = new CountDownLatch(1);

public MyClass(){

}

public void a() {
    new Thread(new Runnable(){
        @Override
        public void run() {
            System.out.println("A: I am going to sleep");
            System.out.println("A: I slept one full day. Feels great.");
            System.out.println("A: Hey B, wake up!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
        }
    }).start();
}

public void b() {
    new  Thread(new Runnable(){
        @Override
        public  void run() {
            System.out.println("B: I am  going to sleep. A, please wake me up.");
            try {
                latch.await();
            } catch (InterruptedException e) {}
            System.out.println("B: Thank you A for waking me up!");
        }
    }).start();
}

public static void main(String[] args) {
    MyClass obj = new MyClass();
    obj.a();
    obj.b();
}

以上代码来自我对类似问题的回答