19

Java Synchronization について疑問があります。クラスに 3 つの Synchronized メソッドがあり、スレッドが 1 つの Synchronized メソッドでロックを取得すると、他の 2 つがロックされるかどうかを知りたいですか? 次の文と混同しているため、この質問をしています。

スレッドがオブジェクトの同期メソッド内にある間、この同期メソッドまたはオブジェクトの他の同期メソッドを実行しようとする他のすべてのスレッドは待機する必要があります。この制限は、既にロックを保持しており、オブジェクトの同期メソッドを実行しているスレッドには適用されません。このようなメソッドは、ブロックされることなく、オブジェクトの他の同期メソッドを呼び出すことができます。もちろん、オブジェクトの非同期メソッドは、任意のスレッドからいつでも呼び出すことができます

4

8 に答える 8

18

Java での同期は、特定のオブジェクトでモニターを取得することによって行われます。したがって、これを行う場合:

class TestClass {
    SomeClass someVariable;

    public void myMethod () {
        synchronized (someVariable) {
            ...
        }
    }

    public void myOtherMethod() {
        synchronized (someVariable) {
            ...
        }
    }
}

次に、これらの 2 つのブロックは、変更されていない間はいつでも 2 つの異なるスレッドの実行によって保護さsomeVariableれます。基本的に、これら 2 つのブロックは変数に対して同期されていると言われていますsomeVariable

メソッドを実行synchronizedすると、基本的に と同じ意味になりsynchronized (this)ます。つまり、このメソッドが実行されるオブジェクトの同期です。

あれは:

public synchronized void myMethod() {
    ...
}

以下と同じ意味:

public void myMethod() {
    synchronized (this) {
       ...
    }
}

したがって、あなたの質問に答えるために-はい、スレッドは両方とも同じモニター、thisオブジェクトのモニターへの参照を保持しているため、異なるスレッドでこれらのメソッドを同時に呼び出すことはできません。

于 2012-06-25T06:59:49.890 に答える
1

はい。
同期メソッドを実行するには、スレッドがオブジェクトのロックを取得する必要があり、一度に 1 つのスレッドのみがオブジェクトのロックを取得できます。

于 2012-06-25T06:55:10.543 に答える
0

各Javaオブジェクト(クラスインスタンス)にはmutexオブジェクトがあります。メソッドの前にあるsynchronizedキーワードは、実行中のスレッドがそのオブジェクトのミューテックスのロックを取得する必要があることを意味します。実際には、

public synchronized doSomething(){
   ...
}

これとまったく同じです:

public  doSomething(){
   synchronized(this){
      ...
   }
}

そうです、クラスインスタンスごとに同期メソッドを実行するスレッドは1つだけです。

変更を保護したいので、これは最適ではない場合があることに注意してください。ただし、同時読み取りでは問題ありません。その場合、synchronizedキーワードの代わりに、ReadWriteLockを調べることをお勧めします。

于 2012-06-25T06:56:17.590 に答える
0

オブジェクトごとに 1 つのロックしかありません。すべての同期メソッドは、このロックによってロックされます。したがって、一度にどのスレッドがロックを取得しても、同期されたすべてのメソッドを通過することが許可されます。ただし、ロックを待機しているスレッドは、ロックを取得するまで同期メソッドに入ることができません。

そのため、一度にスレッド ルールと他のルールのみが同期メソッドに入るのを待つ必要があり、支配スレッドがそのメソッドを実行しているかどうかは関係ありません。

于 2012-06-25T06:59:38.780 に答える
0

はい、ロックを取得したスレッドを除くすべてのスレッドは、ロックが再び解放されるまで待機して、3 つの同期メソッドのいずれかを実行できるようにする必要があります。

同期されたメソッドは、で囲まれた通常のメソッドと同じであることを思い出してください。

synchronized(this) {
    // method body
} 
于 2012-06-25T07:00:06.753 に答える
0

それは真実であり、このようにします。そのオブジェクトのデータの一貫性も必要です。

この検証が存在せず、2 つの異なる同期メソッド xxx() および yyy() によって操作されている変数 x があるとします。

したがって、スレッド A が x=5 を操作するメソッド xxx() のロックを取得し、2 番目のスレッド B がメソッド yyy() のロックを取得して x=-5 を操作する場合、メソッド xxx() の最後にスレッド A は x=5 を予期します。しかし、それは間違っている x=0 になります。

そのため、このように実装されています。

于 2012-06-25T07:01:50.903 に答える
-1

何が混乱しているのかわかりませんが、ロックを取得すると、他のスレッドがロックを保持している間は取得できなくなり、クラスのすべての非静的同期メソッドが同じオブジェクトで同期されるため、質問に対する答えは次のようになります。 「はい」、私があなたを正しく理解していると仮定します。「同期」が他に何を意味するのか、またはそれが他の意味でどのように使用されるのかはわかりません。

于 2012-06-25T06:56:25.257 に答える