gpt4 book ai didi

java - (Java)使用对象wait()和notify()的线程安全

转载 作者:行者123 更新时间:2023-12-02 08:46:16 25 4
gpt4 key购买 nike

我正在寻找一种方法让一个线程等待/ sleep ,直到另一个线程发出信号表明某些东西已准备好。等待线程应该醒来,处理可用的数据,然后返回 sleep 状态,直到另一个线程再次发出信号。

我能找到的最简单的方法是 Object.wait()Object.notify(),它们的行为就像初始化为值 0 的信号量。但是,如果没有围绕notify/waitsynchronized语句,当线程不是监视器所有者时,Java总是抛出IllegalMonitorStateException。所以我只是将它们放在代码周围,如下所示。

线程 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:其他一些类调用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 block)是安全的。语句 synchronized(obj) 获取参数 obj 的锁,因此您可以调用 waitnotify它。它们都要求当前线程持有对象的锁。

您必须小心 removeItem 中锁定两个对象的双重锁定。如果您需要这样做,则必须确保始终以相同的顺序锁定它们,否则可能会造成死锁。

关于java - (Java)使用对象wait()和notify()的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61062991/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com