0

为什么我无法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输出

4

3 回答 3

2

thenotify和 thewait不使用同一台显示器,因此他们没有机会互相“交谈”。

一个简单的解决方法是将阅读器用作主要的监视器:

synchronized (d.reader) {
    try {
        d.reader.wait();
        System.out.println("got notify");
    } catch (Exception e) {
        System.out.println(e);
    }
}
于 2013-07-31T14:49:16.893 回答
0

wait()notify()应该在同一个监视器下。目前notifySerialReader监控thiswait监控下d是什么ThreadMain

顺便说一句,使用一个notifyAll()建议notify()

于 2013-07-31T14:49:18.843 回答
0

您的代码中有两个问题。

正如其他人所建议的那样。您需要使用相同的锁来使用通知和等待。您正在使用不同的对象来等待和通知

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

解决上述两个问题的方法是使用闩锁。试试 CountDownLatch 见下文

导入 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();
}

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

于 2013-08-02T10:38:52.420 回答