[英](Java) Thread safety using Object wait() and notify()
我一直在寻找一种方法让一个线程等待/休眠,直到另一个线程发出信号表明某事已准备就绪。 等待的线程应该唤醒,处理可用的数据,然后 go 回到睡眠状态,直到另一个线程再次发出信号。
The simplest method I could find was Object.wait()
and Object.notify()
, which behaved like a semaphore initialised to value 0. However, without the synchronized
statements around notify/wait
, Java always threw IllegalMonitorStateException
when the thread was not the监控所有者。 所以我只是把它们放在代码周围,如下所示。
线程1:运行无限循环
public class Main {
private Handler handler; // only one instance (singleton pattern)
public void listen() {
while (true) {
try {
synchronized (handler) {
handler.wait();
int value = handler.getSize();
// do something
}
} catch (InterruptedException e) {
// ...
}
}
}
}
线程 2:其他一些 class 调用 removeItem
public class Handler {
// SINGLETON PATTERN - ONLY ONE INSTANCE
private ArrayList<Integer> sharedList;
private Handler() {
sharedList = new ArrayList<>();
}
public void addItem(Integer i) {
synchronized (sharedList) {
// add to list
}
}
public void removeItem(int i) {
synchronized (sharedList) {
// remove item
// notify that something is removed
synchronized (this) {
this.notify(); // this == handler
}
}
}
public int getSize() {
synchronized (sharedList) {
return sharedList.size();
}
}
}
它似乎工作得很好,但不确定是否存在隐藏的错误。 我的问题是:这安全吗? wait
是否释放handler/this
的实例锁,以便notify
可以获取锁?
同步块是安全的。 语句synchronized(obj)
获取参数obj
的锁,因此您可以对其调用wait
和notify
。 它们都要求当前线程持有 object 上的锁。
您必须小心您在removeItem
中锁定两个对象的双重锁定。 如果你需要这个,你必须确保你总是以相同的顺序锁定它们,否则,你可能会造成死锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.