公平なロック/不公平なロック
公平なロックとは、複数のスレッドがその順序でロックを取得することを意味します。ロックを申請してください。
不公平なロックとは、複数のスレッドがロックを取得する順序が、ロックを適用する順序ではないことを意味します。最初に適用するスレッドよりも後から適用するスレッドが先にロックを取得する可能性があります。優先順位の逆転や飢餓が発生する可能性があります。
Java ReentrantLock の場合、コンストラクターを通じてロックが公正なロックであるかどうかを指定します。デフォルトは不公平なロックです。不公平なロックの利点は、スループットが公平なロックよりも高いことです。
Synchronized の場合、これも不当なロックです。 ReentrantLock のような AQS を介したスレッド スケジューリングを実装していないため、公平なロックに変える方法はありません。
リエントラント ロック
リエントラント ロックは再帰的ロックとも呼ばれ、同じスレッドが外側のメソッドでロックを取得すると、内側のメソッドに入るという意味です。自動的に取得されます。少し抽象的ですが、以下にコード例を示します。
Java ReentrantLock の場合、その名前はリエントラント ロックとして認識され、Reentrant Lock となります。
同期の場合、これは再入可能なロックでもあります。リエントラント ロックの利点の 1 つは、デッドロックをある程度回避できることです。
synchronized void setA() throws Exception{ Thread.sleep(1000); setB(); } synchronized void setB() throws Exception{ Thread.sleep(1000); }
上記のコードはリエントラント ロックの機能です。リエントラント ロックでない場合、現在のスレッドで setB が実行されず、デッドロックが発生する可能性があります。
排他ロック/共有ロック
排他ロックとは、一度に 1 つのスレッドのみがロックを保持できることを意味します。
共有ロックは、ロックを複数のスレッドで保持できることを意味します。
Java ReentrantLock の場合、これは排他的ロックです。ただし、Lock の別の実装クラスである ReadWriteLock の場合、その読み取りロックは共有ロックであり、その書き込みロックは排他ロックです。
読み取りロックの共有ロックにより、同時読み取りが非常に効率的に行われ、読み取り、書き込み、書き込み、書き込みのプロセスが相互に排他的になります。
排他的ロックと共有ロックも AQS を通じて実装されます。排他的ロックまたは共有ロックは、さまざまな方法で実装されます。
Synchronized の場合は、もちろん排他ロックです。
相互排他ロック/読み取り/書き込みロック
上記の排他ロック/共有ロックは広義の用語であり、ミューテックス ロック/読み取り/書き込みロックは特定のものです。実現。
Java におけるミューテックス ロックの具体的な実装は、ReentrantLock です。
Java における読み取り/書き込みロックの具体的な実装は ReadWriteLock です。
オプティミスティック ロック/ペシミスティック ロック
オプティミスティック ロックとペシミスティック ロックは、特定の種類のロックを指すのではなく、同時実行性と同期の観点を指します。
悲観的ロックでは、同じデータに対する同時操作は必ず変更されると考えられ、変更がなくても変更されたものとみなされます。したがって、同じデータに対する同時操作の場合、悲観的ロックはロックの形式になります。悲観的に言えば、ロックを行わない同時操作は間違いなく問題を引き起こすと思います。
オプティミスティック ロックでは、同じデータに対する同時操作は変更されないと考えられます。データを更新する場合、更新を試行し、常にデータを再更新することでデータが更新されます。楽観的に考えれば、ロックを行わなくても同時操作に問題はありません。
上記の説明から、悲観的ロックは書き込み操作が多いシナリオに適しており、楽観的ロックは読み取り操作が多いシナリオに適していることがわかります。ロックしないとパフォーマンスが大幅に向上します。 。
Java での悲観的ロックの使用は、さまざまなロックを使用することです。
Java におけるオプティミスティック ロックの使用は、ロックフリー プログラミングであり、CAS アルゴリズムがよく使用されます (代表的な例として、CAS スピンによるアトミック操作の更新を実装するアトミック クラス)。
セグメント ロック
セグメント ロックは実際にはロックの設計であり、特定のロックではありません。ConcurrentHashMap の場合、その同時実行実装はセグメント ロックを通じて効率的な同時操作が実現されます。
ConcurrentHashMap を例に、セグメント ロックの意味と設計思想について話しましょう。ConcurrentHashMap のセグメント ロックはセグメントと呼ばれ、HashMap (JDK7 および JDK8 の HashMap の実装) の構造に似ています。内部には Entry 配列があり、配列内の各要素はリンク リストであり、ReentrantLock でもあります (セグメントは ReentrantLock を継承します)。
要素を配置する必要がある場合、ハッシュマップ全体をロックするのではなく、最初にハッシュコードを使用して要素を配置する必要があるセグメントを認識し、次にこのセグメントをロックします。つまり、セグメント内に配置されない限り、真の並列挿入が実現されます。
ただし、サイズをカウントする場合、ハッシュマップのグローバル情報を取得する場合、カウントするにはすべてのセグメントのロックを取得する必要があります。
セグメント化されたロックの設計目的は、ロックの粒度を調整することです。操作で配列全体を更新する必要がない場合、配列内の 1 つの項目だけがロックされます。
バイアス ロック/軽量ロック/重量ロック
これら 3 種類のロックはロックのステータスを指し、同期用です。 Java 5 では、ロック アップグレード メカニズムを導入することにより、効率的な同期が実現されます。これら 3 つのロックのステータスは、オブジェクト モニターのオブジェクト ヘッダー内のフィールドによって示されます。
バイアスされたロックとは、同期コードの一部が常に 1 つのスレッドによってアクセスされ、そのスレッドが自動的にロックを取得することを意味します。ロックを取得するコストを削減します。
軽量ロックとは、ロックがバイアスされたロックであり、別のスレッドによってアクセスされると、バイアスされたロックが軽量ロックにアップグレードされることを意味します。他のスレッドはブロックせずにスピンを通じてロックを取得しようとし、パフォーマンスが向上します。
ヘビーウェイト ロックとは、ロックが軽量ロックの場合、別のスレッドが回転しているにもかかわらず、永遠にスピンが継続するわけではなく、一定回数スピンした時点ではまだ取得されていないことを意味します。はブロッキングに入り、ロックは重量ロックに拡張されます。重いロックは他のアプリケーション スレッドをブロックし、パフォーマンスを低下させます。
スピン ロック
Java では、スピン ロックは、ロックを取得しようとするスレッドがすぐにはブロックされず、ループを使用してロックを取得しようとすることを意味します。この利点は、スレッド コンテキストの切り替えの消費を削減できることですが、欠点は、ループが CPU を消費することです。
php 中国語 Web サイト、無料の Java 入門チュートリアル が多数あり、オンラインで学習することを歓迎します。
以上がJava ロックの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。