wait() does not free all current locks, how it can be done?

Gangnus :

According to Java doc, when obj1.wait() happens, "The thread releases ownership of this monitor and waits until another thread notifies..."

So, the lock of obj1 is freed, while the current thread is waiting. But what about all other locks? It is possible, that the piece of the code is locking two objects:

synchronized(obj2){
    f1();
    synchronized(obj1){
        f2();
        obj1.wait();
    }
}

Obj2 won't be freed, but the thread does not run, another thread will wait for freeing of obj2 in vain... I don't understand the reason of that continuing locking of obj2. But OK, it is as it is.

But how can I organize this waiting better, how can I unlock for the time of waiting all or at least several current locks?

Marcono1234 :

You could use Locks and Conditions which are more flexible than sychronized statements.

For your example you could replace obj2 with a ReentrantLock:

Lock lock2 = new ReentrantLock();

try {
    // Blocks until the lock is acquired, just like a `synchronized` statement
    lock2.lock();
    f1();

    synchronized (obj1) {
        f2();
        lock2.unlock();
        obj1.wait();
        lock2.lock();
    }
}
// Use `finally` to make sure the lock is always released, even if an exception is thrown
finally {
    // Exception might have been thrown before current thread could acquire lock again, cannot 
    // unlock then
    if (lock2.isHeldByCurrentThread()) {
        lock2.unlock();
    }
}

However, this would allow another thread to acquire lock2 before the current thread starting waiting for obj1. If this is not desired you could replace obj1 with a Lock instead and wait for obj2.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=81408&siteId=1