1

これはよくある質問のようですが、見つけられませんでした。次のコードがあるとします。

public class MyClass {
    private AnotherClass mField;

    public void changeOne(AnotherClass newOne) {
        // <...> lines of code here
        synchronized (mField) {
            mField = newOne;
        }
        // <...> lines of code here

    }

    public void changeTwo(AnotherClass newTwo) {
        // <...> lines of code here
        mField = newTwo;
        // <...> lines of code here
    }
}

changeOne()changeTwo()が異なるスレッドから呼び出されたとしましょう。による変更changeOne()から保護するには、同期ブロックを入れるだけで十分ですか? または、ブロックに変更された各場所を明示的にラップする必要がありますか? (同期メソッドなどは残しておいてください)。mFieldchangeTwo()mFieldsynchronized

4

2 に答える 2

4

mField同期ブロック (または) 同期メソッドを使用して、すべての変更を明示的に同期する必要があります。mFieldそうしないと、一度に changeTwo を実行することで、複数のスレッドが変更される可能性があります。

編集:Tedd Hoppが示唆したように、変数が揮発性でない場合、読み取りも同期する必要があり、ロックを取得する必要があります。同じオブジェクトにある必要があります。

于 2012-12-28T06:12:59.523 に答える
0

いいえ、そうではありません。両方のスレッドが同じロックを取得しようとする必要があります。次に、スレッド A が最初にロックを取得した場合、スレッド B は A が解放するまでブロックされます。ロックは、A と B の両方に共通の任意のオブジェクトにすることができます。あなたの場合の最も典型的なものは

public class MyClass {
    private AnotherClass mField;

        public synchronized void changeOne(AnotherClass newOne) {
             ...
        }

        public synchronzied void changeTwo(AnotherClass newTwo) {
             ...
        }

この場合this、ロックとして使用されます。それは(ほぼ)同等です

    public void changeOne(AnotherClass newOne) {
         synchronized(this) {
              ...
         }
    }

    public void changeTwo(AnotherClass newOne) {
         synchronized(this) {
              ...
         }
    }

同期されたメソッドはよりコンパクトですが、同期されたブロックはより柔軟です。同期ブロックを使用すると、任意のオブジェクトをロックできますが、同期メソッドを使用すると、 onthisまたは静的メソッドを暗黙的にロックできますclass

于 2012-12-28T06:20:39.473 に答える