0

重複の可能性:
同期ブロック vs 同期メソッド?

この質問に対する受け入れられた回答から: Javaクリティカルセクションでは、何を同期する必要がありますか? 私はそれを学びます

public synchronized void foo() {
    // do something thread-safe
}

と:

public void foo() {
    synchronized (this) {
        // do something thread-safe
    }
}

まったく同じことをします。しかし、最初のケースでは、オブジェクトの 1 つのメソッドだけを同期させ、2 番目のケースでは、オブジェクト全体にアクセスできないようにします。では、なぜこの 2 つのコード スニペストが同じことを行うのでしょうか?

4

4 に答える 4

6

あなたは物事を混ぜているようです。

まずは

public synchronized void method() {
}

同期の観点からは、次のものと同等です。

public void method() {
    synchronized (this) {
    }
}

長所/短所は既に述べられており、さまざまな重複により詳細情報が得られます。

第二に、

synchronized(someObject) {
    //some instructions
}

これは、同期ブロック内の命令を 2 つのスレッドで同時に実行できないことを意味します。これは、実行するためにモニターを取得する必要があるsomeObjectためです。(これは、 someObject が変更されない最終参照であると想定しています)。

あなたの場合、someObjectたまたまthis.

Any code in your object that is not synchronized, can still be executed concurrently, even if the monitor on this is held by a thread because it is running the synchronized block. In other words, synchronized(this) does NOT "lock the whole object". It only prevents 2 threads from executing the synchronized block at the same time.

Finally, if you have two synchronized methods (both using this as a lock), if one thread (T1) acquires a lock on this to execute one of those 2 methods, no other thread is allowed to execute any of the two methods, because they would need to acquire the lock on this, which is already held by T1.

That situation can create contention in critical sections, in which case a more fine grained locking strategy must be used (for example, using multiple locks).

于 2012-08-16T11:24:43.957 に答える
1

彼らは同じことをします。最初の形式は、2番目の形式の省略形です。

2つの構成の小さな違いの1つは、これです。同期されたブロックは、(op-code)命令とmonitorenter(op-code )命令にコンパイルされます。同期されたメソッドは、コンパイルされると、実行時定数プール内でフラグによって区別されます。フラグは、JVMのメソッド呼び出し命令によってチェックされます。ただし、この違いは実際にはあまり重要ではありません。0xC2monitorexit0xC3ACC_SYNCHRONIZED

于 2012-08-16T06:11:54.227 に答える
1

オブジェクトを同期するのではなく、コード ブロックを同期します。最初のコード ブロックはメソッド自体ですが、2 番目のコード ブロックはsynchronizedブロックです。

オブジェクトは、複数のスレッドがそのコード ブロックに同時に入るのを防ぐためにロックを提供するだけです。最初のケースでは、thisオブジェクト (メソッドが呼び出されるオブジェクト) が暗黙的にロックとして使用されますが、2 番目のケースでは、必ずしもオブジェクトである必要はなくthis、他のオブジェクトでもかまいません。

于 2012-08-16T05:58:17.587 に答える
0

彼らは同じことをしません。最初の部分は最初から最後まで同期されています。2番目は、ブロックを同期するだけです(メソッド全体ではありません)。2 つ目はある程度の柔軟性があります。

于 2012-08-16T05:45:05.477 に答える