ホームページ  >  記事  >  Java  >  同期とロックの違いは何ですか?

同期とロックの違いは何ですか?

青灯夜游
青灯夜游オリジナル
2020-11-19 11:38:2968603ブラウズ

違い: 1. Lock はインターフェースであり、synchronized は Java のキーワードです。 2. Synchronized は、例外が発生したときに保持しているロックを自動的に解放するため、デッドロックは発生しません。例外が発生した場合、Synchronized は保持しているロックを積極的に解放せず、ロックを手動で解放する必要があるため、デッドロックが発生する可能性があります。

同期とロックの違いは何ですか?

#分散開発では、ロックはスレッドを制御する重要な方法です。 Java は、この目的のために、同期とロックという 2 つのロック メカニズムも提供します。

0. 同期実装の原則

Java のすべてのオブジェクトはロックとして使用でき、これが同期を実現するための同期の基礎です:

  • 通常の同期メソッド、ロックは現在のインスタンス オブジェクトです

  • 静的同期メソッド、ロックは現在のクラスのクラス オブジェクトです

  • 同期メソッド ブロック、ロックは括弧内のオブジェクトです。
    スレッドが同期コード ブロックにアクセスするときは、まずロックを取得する必要があります。スレッドが終了するか例外をスローするときは、ロックを解放する必要があります。では、このメカニズムはどのように実装されているのでしょうか?まずは簡単なコードを見てみましょう:

package cn.alibab.javap;public class SynchronizedTest {

    public synchronized void test1(){

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

        }
    }
}

javap ツール (javap は Java コンパイル後のクラス ファイルの分解ツール) を使用して、生成されたクラス ファイル情報を表示し、実装を分析します。上記からわかるように、同期コード ブロックは、monitorenter 命令とmonitorexit 命令を使用して実装されています。ここでは、JVM の基礎となる実装を確認する必要があります) は、メソッド修飾子の ACC_SYNCHRONIZED 実装に依存しています。

同期とロックの違いは何ですか?同期コード ブロック

: コンパイル後に、monitorenter 命令が同期コード ブロックの先頭に挿入され、monitorexit 命令が同期コード ブロックの末尾に挿入されます。各monitorenterに対応するmonitorexitがあることを確認します。すべてのオブジェクトにはモニターが関連付けられており、モニターを保持するとロック状態になります。スレッドがmonitorenter命令を実行すると、オブジェクトに対応するモニターの所有権を取得しようとします、つまり、オブジェクトのロックを取得しようとします; [並行プログラミングの技術からの抜粋]

同期とロックの違いは何ですか? #Synchronized メソッド
: synchronized メソッドは、invokevirtual 命令や areturn 命令などの通常のメソッド呼び出しおよびリターン命令に変換されます。synchronized によって変更されたメソッドを実装するための VM バイトコード レベルでの特別な命令はありません。メソッドがクラス ファイルのメソッド テーブルに追加されます。access_flags フィールドの同期フラグの位置は 1 で、メソッドが同期メソッドであり、メソッドを呼び出すオブジェクト、またはメソッドが属するクラスを使用して、そのメソッドを表すことを示します。 JVM の内部オブジェクトの Klass をロック オブジェクトとして使用します。 (抜粋: http://www.cnblogs.com/javaminer/p/3889023.html)

#同期とロックの違い

# 違いは次のとおりです:

出典: lock はインターフェース、synchronized は Java のキーワード、synchronized は組み込み言語実装です。

同期とロックの違いは何ですか?例外が発生したときにロックが解放されるかどうか:
synchronized は、例外が発生したときに保持しているロックを自動的に解放するため、デッドロックは発生しません。ロックで例外が発生すると、は保持しているロックを積極的に解放しないため、ロックを解放するには手動でロックを解除する必要があり、デッドロックが発生する可能性があります。 (デッドロックの発生を避けるために、同期コードブロックをtry catchでラップし、最後にunlockを書き込むのが最善です。)

  • 割り込みに応答するかどうか
    ロックはロックを待っています 割り込みを使用して待機を中断できますが、同期はロックが解放されるのを待つことしかできず、割り込みに応答できません;

  • ロックを取得するかどうか知っていますか?
    Lock は、trylock を使用して、ロックが取得されたかどうかを確認できます。同期はできません。

  • Lock は、複数のスレッドによる読み取り操作の効率を向上させることができます。 (読み取りと書き込みの分離は、readwritelock によって実現できます)

  • パフォーマンスの点では、リソースの競争が激しくなければ、2 つのパフォーマンスはほぼ同じです。リソースの競合は非常に激しいため (つまり、多数のスレッドが同時に競合します)、現時点では、Lock のパフォーマンスは同期よりもはるかに優れています。したがって、使用する場合には適切な状況に応じて選択する必要があります。


  • synchronized は、Object オブジェクト自体の wait、notify、notifyAll スケジューリング メカニズムを使用しますが、Lock は Condition を使用してスレッド間のスケジュールを設定できます。
  • ##1. synchronized と lock

  • synchronized の使用法の違い: このコントロールを、同期する必要があるオブジェクトに追加します。Synchronized は、メソッドまたは特定のコード ブロックに追加できます。 、括弧 ロックする必要があるオブジェクトを示します。
  • lock: 通常、ロックとして ReentrantLock クラスが使用されます。ロックおよびロック解除の場所は、lock() および lock() を通じて表示する必要があります。したがって、デッドロックを防ぐために、unlock() は通常、finally ブロックに記述されます。

  • 2. synchronized と lock のパフォーマンスの違い

  • synchronized は JVM 実行用にホストされ、
および lock はロックを制御するために Java で書かれたコードです。

Java1.5 では、同期はパフォーマンスが非効率的です。これは操作インターフェイスの呼び出しを必要とする負荷の高い操作であるため、ロックはロック以外の操作よりも多くのシステム時間を消費する可能性があります。これに対して、Java が提供する Lock オブジェクトを使用するとパフォーマンスが向上します。

しかし、Java1.6 では変更が加えられています。同期はセマンティクスが非常に明確であり、適応スピン、ロックの削除、ロックの粗密化、軽量ロック、バイアスされたロックなどを含む多くの最適化を実行できます。結果として、Java1.6 での synchronize のパフォーマンスは Lock と比べても劣りません。公式はまた、より多くの同期もサポートしており、将来のバージョンでは最適化の余地があると述べています。

2 つのメカニズムの具体的な違い:
synchronized は当初、CPU ペシミスティック ロック メカニズムを使用していました。つまり、スレッドが排他的ロックを取得しました。 排他的ロックとは、他のスレッドがロックを解放するのを待つためにブロックのみに依存できることを意味します。 CPU 変換スレッドがブロックされると、スレッドのコンテキスト スイッチが発生し、多くのスレッドがロックを競合すると、CPU のコンテキスト スイッチが頻繁に発生し、効率が非常に低下します。

ロックは楽観的ロックを使用します。いわゆる楽観的ロックとは、毎回ロックを行わずに競合がないと仮定して操作を完了するもので、競合により失敗した場合は成功するまで再試行されます。楽観的ロックによって実装されるメカニズムは、CAS 操作 (比較と交換) です。 ReentrantLock のソース コードをさらに研究すると、ロックを取得するためのより重要なメソッドの 1 つが CompareAndSetState であることがわかります。これは実際には、呼び出された CPU によって提供される特別な命令です。

最新の CPU は、共有データを自動的に更新し、他のスレッドからの干渉を検出できる命令を提供しており、compareAndSet() はロックの代わりにこれらを使用します。このアルゴリズムはノンブロッキング アルゴリズムと呼ばれます。これは、1 つのスレッドの障害または一時停止が他のスレッドの障害または一時停止に影響を与えないことを意味します。

3. 同期とロックの使用の違い

通常の状況では、同期プリミティブと ReentrantLock の間に違いはありませんが、非常に複雑な同期アプリケーションでは、使用を検討してください。 ReentrantLock、特に次の 2 つの要件が発生した場合。

1. ロックの制御を待機している間、スレッドを中断する必要があります
2. 一部の待機通知は個別に処理する必要があります。ReentrantLock の Condition アプリケーションは、どのスレッドに通知するかを制御できます
3. 公平なロック機能を使用すると、各受信スレッドはキューに並んで待機します

詳しい説明をしましょう...

まず最初のケースについて説明しましょう。 ReentrantLock. の場合、割り込みロックを無視し、割り込みロックに応答するため、非常に柔軟です。例: 2 つのスレッド A と B がロックをめぐって競合する場合、スレッド A がロックを取得し、スレッド B は待機します。ただし、スレッド A は現時点で処理すべきことが多すぎるため、戻りません。スレッド B は処理できない可能性があります。話を中断して、このロックを待つのをやめて、他のことに目を向けたいと思います。現時点では、ReentrantLock は 2 つのメカニズムを提供します: 割り込み可能/非割り込み可能
まず、B スレッドはそれ自体に割り込みます (または他のスレッドが割り込みます)。ただし、ReentrantLock は応答せず、B スレッドを待機させ続けます。 , どのように割り込んでも、私はそれを無視します (これは同期プリミティブです);
次に、B スレッドがそれ自体に割り込み (または他のスレッドが割り込み)、ReentrantLock が割り込みを処理し、ロックを待機しなくなります。 、完全に諦めます。

プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !

以上が同期とロックの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。