为什么我无法在此代码中收到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
行
答案 0 :(得分:2)
notify
和wait
不使用相同的监视器,因此他们无法相互“交谈”。
一个简单的解决方法是将阅读器用作主屏幕中的显示器:
synchronized (d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
答案 1 :(得分:0)
您的wait()
和notify()
应位于同一监视器下。目前notify
在SerialReader
监视this
和wait
监视d
下ThreadMain
。
顺便说一句建议使用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();
}
以上代码来自我对类似问题的回答