为什么notify方法应该在synchronized块中?

whi*_*hat 5 java multithreading

请考虑以下代码: -

class CalculateSeries implements Runnable{
    int total;
    public void run(){
        synchronized(this){                          // *LINE 1* 
            for(int i = 1; i <= 10000; i++) {
                total += i;
            }

            notify(); //Notify all the threads waiting on this instance of the class to wake up
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

另一个类通过在同步块内获取锁定来等待此类的实例.但是,如果我不在同步块中保存run方法中的代码,那么我得到IllegalMonitorStateException.

notify()应该意味着给所有等待的线程发出信号.那为什么它应该在同步块内呢?

Mic*_*rdt 5

notify() 应该意味着向所有等待的线程发出信号。

实际上,没有。它向一个任意选择的等待线程发出信号。notifyAll()向他们发出信号。

那为什么它应该在同步块内呢?

因为等待不是为了它自己而发生的。你检查一个条件,如果它不满足,你就等到有人告诉你现在可能满足(然后你再次检查)。如果没有同步,您将在检查条件和实际等待之间出现竞争条件。

  • 这解释了为什么 `wait()` 必须在 `synchronized` 内,而不是 `notify()`。请注意,例如,[在 C++ API 中,明确不鼓励这样做](http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one)。所以它留下了为什么 Java 需要它的问题。 (4认同)