我正在学习多线程,我正在尝试了解如何使用Object类的wait和notify方法。我已经浏览了这个链接https://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example,并编写了以下程序
服务员
public class Waiter implements Runnable {
private Message m;
public Waiter(Message m) {
this.m = m;
}
public void run() {
String name = Thread.currentThread().getName();
System.out.println(t1 + " thread waiting for message");
synchronized (m) {
try {
m.wait();
System.out.println(t1 + " " + m.getText());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(t1 + " thread waiting for message");
}
}
通告
public class Notifier implements Runnable {
private Message m;
public Notifier(Message m) {
this.m = m;
}
public void run() {
synchronized (m) {
try {
Thread.sleep(2000);
m.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试
public class WaitNotifyTest {
public static void main(String[] str) {
Message m = new Message("hello");
new Thread(new Waiter(m), "t1").start();
new Thread(new Waiter(m), "t2").start();
new Thread(new Notifier(m)).start();
}
}
当我执行程序时,它有时会正常终止,有时会无限期地等待,有时一个线程终止而另一个无限期地等待。谁能告诉我这里有什么问题?
另外,我想了解一些等待和通知方法的实时应用示例。
答案 0 :(得分:1)
当你在做等待时,最好的做法是在一个带有条件的while循环中进行。可能有线程将通知的情况,然后其他线程进入等待状态。所以线程将始终处于等待状态
修改后的代码:
public class Waiter implements Runnable {
private Message m;
public Waiter(Message m) {
this.m = m;
}
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " thread waiting for message");
synchronized (m) {
try {
while (m.getText() == null) {
m.wait();
}
System.out.println(name + " " + m.getText());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name + " thread waiting for message");
}
}
public class Notifier implements Runnable {
private Message m;
public Notifier(Message m) {
this.m = m;
}
public void run() {
synchronized (m) {
m.setText("hello");
m.notifyAll();
}
}
}
public class WaitNotifyTest {
public static void main(String[] str) {
Message m = new Message();
new Thread(new Waiter(m), "t1").start();
new Thread(new Waiter(m), "t2").start();
new Thread(new Notifier(m)).start();
}
}