5

synchronized私は次のようなブロックを書いていました:

synchronized(foobar) {
    // do something
}

しかし、最近、誰かが次のように書いているのを見ました。

synchronized(foobar) {
    // do something
    foobar.notifyAll();
}

foobar.notifyAll();必要ですか?省略したらどうなりますか?

4

4 に答える 4

4

短い答えは、それはあなたが何をしているかに依存するということです。

同期ブロックの目的が、データ構造へのアクセス/更新が安全に実行されるようにすることだけである場合、notify()またはnotifyAll()目的を果たしません。

一方、目標が「条件変数」を実装することである場合、notify()ornotifyAll()呼び出しは次のwaitような呼び出しで機能します...例:

private boolean flag;
private final Object mutex = new Object();

public void awaitFlag(boolean flag) {
    synchronized (mutex) {
        while (this.flag != flag) {
            mutex.wait();
        }
    }
}

public void setFlag(boolean flag) {
    synchronized (mutex) {
        this.flag = flag;
        mutex.notifyAll();
    }
}

上記は、 がまたはになるawaitFlag()のを待機するためにスレッドが呼び出す単純なメカニズムを実装しています。別のスレッドがフラグを変更するために呼び出すと、現在フラグが変更されるのを待っているすべてのスレッドが によって起こされます。これは、コードの動作に が不可欠な例です。flagtruefalsesetFlag()notifyAll()notifyAll()


notifyまたはnotifyAllコードが必要かどうかを理解するには、他のコードwait同じミューテックス/ロック オブジェクトを呼び出す可能性があるかどうかを判断する必要があります。

于 2013-02-12T16:44:09.820 に答える
4

これを行う必要はありません。foobarオブジェクト (ここでは ) が通知を待っている場合にのみ実行する必要があります。通知のみこのオブジェクトのモニターで待機しているすべてのスレッドを起こします。

于 2013-02-12T15:58:49.200 に答える
2

Java では、 と を使用wait()notify()て、notifyAll()スレッドの調整を実現できます。Javaでwaitとnotifyを使用する方法を参照してください。

于 2013-02-12T15:59:06.797 に答える
1

notifyAll() は、foobar.wait() でスリープしている他のスレッドに、現在のスレッドがロックを解放しようとしていることを伝え、リソースを再び競合できるようにします。

于 2013-02-12T15:59:27.860 に答える