Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

multithreading - why wait/notify/notifyAll methods are not synchronized in java ?

in Java whenever we need to call wait/notify/notifyAll, we need to have access to object monitor (either through synchronized method or through synchronized block). So my question is why java didn't go for synchronized wait/notify methods removing the restriction of calling these methods from synchronized block or methods.

In case these are declared as synchronized, it would have automatically taken the monitor access.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For notify and notifyAll, the problem with your idea is that when you notify you also have other stuff you're typically doing in the same synchronized block. So making the notify method synchronized wouldn't buy you anything, you'd still need the block. Likewise wait has to be in a synchronized block or method in order to be useful, such as being inside a spinlock where the test has to be synchronized anyway. So the granularity of locking is all wrong for what you suggest.

Here's an example, this is about the simplest queue implementation you can have in Java:

public class MyQueue<T> {

    private List<T> list = new ArrayList<T>();

    public T take() throws InterruptedException {
        synchronized(list) {
            while (list.size() == 0) {
                list.wait();
            }
            return list.remove(0);
        }
    }

    public void put(T object) {
        synchronized(list) {
            list.add(object);
            list.notify();
        }
    }
}

So you can have producer threads that add things to the queue and consumer threads that take things out. When a thread goes to get something out of the queue it needs to check within the synchronized block that there's something in the list, and once it's been notified it needs to reacquire the lock and make sure there is still something in the list (because some other consumer thread could have stepped in and grabbed it).There's also the "spurious wake-up" phenomenon: you can't rely on getting woken up as sufficient evidence that something happened, you need to check that whatever condition you're waiting for is actually true, and that needs to be done within the synchronized block.

In both of these cases, checks surrounding the wait need to be made with the lock held so that when the code takes action based on those checks it knows that those results are currently valid.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...