简体   繁体   English

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

[英](Java) Thread safety using Object wait() and notify()

I was looking for a way to make one thread wait/sleep until another thread signalled that something was ready.我一直在寻找一种方法让一个线程等待/休眠,直到另一个线程发出信号表明某事已准备就绪。 The waiting thread should wake up, process the data that was made available, then go back to sleep until the other thread signalled again.等待的线程应该唤醒,处理可用的数据,然后 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 monitor owner. 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监控所有者。 So I simply put them around the code like shown below.所以我只是把它们放在代码周围,如下所示。

THREAD 1: running infinite loop线程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) {
                // ...
            }
        }
    }
}

THREAD 2: Some other class calls removeItem线程 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();
        }
    }
}

It seems to work perfectly fine but not sure if there is a hidden bug.它似乎工作得很好,但不确定是否存在隐藏的错误。 My question is: Is this safe?我的问题是:这安全吗? Does wait release the instance lock for handler/this so notify can acquire the lock? wait是否释放handler/this的实例锁,以便notify可以获取锁?

Synchronized blocks are safe.同步块是安全的。 The statement synchronized(obj) acquires the lock of the argument obj , so you can call wait and notify on it.语句synchronized(obj)获取参数obj的锁,因此您可以对其调用waitnotify They both require that the current thread holds the lock on the object.它们都要求当前线程持有 object 上的锁。

You have to be careful about the double-locking you have in removeItem where you lock two objects.您必须小心您在removeItem中锁定两个对象的双重锁定。 If you ever need this, you have to make sure that you always lock them in the same order, otherwise, you may create a deadlock.如果你需要这个,你必须确保你总是以相同的顺序锁定它们,否则,你可能会造成死锁。

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

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