java - 如何使 notify() 与 wait() 一起正常工作
问题描述
我正在尝试制作一个程序来模拟一个非常简单的洗碗机,它有三个线程。第一个线程负责加水,第二个线程打开设备的门,应该强制加水线程等到第三个线程 notify()。系统运行,但它永远不会停止,并且 notify() 永远不会工作。
import java.util.logging.Level;
import java.util.logging.Logger;
public class threadexample {
public static boolean flag = false;
void Open() throws InterruptedException {
synchronized (threadexample.this) {
flag = true;
Thread.sleep(2000);
System.out.println("producer thread paused");
wait();
System.out.println("Resumed");
}
}
void Close() throws InterruptedException {
synchronized (threadexample.this) {
flag = false;
Thread.sleep(6000);
System.out.println("System resuming..");
notifyAll();
Thread.sleep(2000);
}
}
public static void main(String[] args) throws InterruptedException {
threadexample closing = new threadexample();
threadexample openning = new threadexample();
final Door door = new Door();
// Create a thread object that calls pc.produce()
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
if (flag == false) {
for (int check = 0; check <= 8; check++) {
if (check == 1) {
System.out.println("Adding Water..." + Thread.currentThread().getName());
} else {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
if (flag == true) {
try {
closing.Close();
} catch (InterruptedException ex1) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
}
}
}
try {
Thread.sleep(4000);
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
openning.Open();
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
closing.Close();
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
t1.start();
t2.start();
t3.start();
}
}
解决方案
1)你打电话时wait
没有检查你等待的事情是否已经发生。如果您wait
为已经发生的事情,您将永远等待,因为notify
不会再次被调用。
2) 你sleep
在拿着锁的时候打电话。那没有意义。
3) 你有:
threadexample closing = new threadexample();
threadexample openning = new threadexample();
和:
synchronized(threadexample.this)
所以你创建了两个实例,threadexample
每个线程在它自己的实例上同步threadexample
。那也不对。
推荐阅读
- vba - 将 Visio 文档的特定页面放入 Word 的 VB 代码
- javascript - 如何更改 vuetify 数据表中的字体大小和/或样式?
- ios - 将 ARFrame#capturedImage 转换为视图大小
- ejabberd - 如何在 ejabberd 中设置 mod_http_upload
- jquery - 如何使用 jquery 在页面加载时每 2 秒定期单击按钮元素 3 次?
- arduino - Switch Case Arduino 的奇怪之处
- kotlin - Kotlin 函数引用是否有一个简单的空安全运算符?
- dart - Dart 私有数组
- amazon-dynamodb - 如何查询 AWS dynamodb 以获取每一小时、每一天和 30 天的数据?
- java - 我的 RecyclerViw 适配器出错,填充了 firebase 数据