繁体   English   中英

(Java) 线程安全使用 Object wait() 和 notify()

[英](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的锁,因此您可以对其调用waitnotify 它们都要求当前线程持有 object 上的锁。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM