Javaロックから分散ロックへ

Javaロックから分散ロックへ

[[436819]]

序文

Synchronized ロックと ReentrantLock ロックは、並行プログラミングでよく使用されます。分散ロックはビジネス開発プロセスでも使用できます。分散ロックによく使用されるフレームワークは、Redis をベースにした分散ロック フレームワークである Redisson と、Zookeeper をベースにした分散ロック フレームワークである Curator です。もちろん、ロックを実装する方法は他にもありますが、ここでは紹介しません。

この記事は主に、Java ロックと分散ロックのソースコードを研究した後の要約です。

1ロックの最も基本的な要素

なぜロックを使用するのですか?

ロックが必要な理由については、答えは明白です。「マルチスレッドの同時実行の競合を回避するため」です。

複数のスレッドでパブリック データを変更する場合は、1 つのスレッドだけが操作を実行していることを確認する必要があります。ここでのパブリック データは、パブリック変数またはデータベース内のデータ行になります。

ロックの基本要素

ロックが必要な理由がわかったら、ロックの基本要素を導き出すことができます。

  • ロックサイン: 正常にロックするには何が必要ですか?
  • ロックホルダー: どのスレッドがロックを保持していますか?
  • ロック再入: 自分自身をロックした後、再度ロックしますか?
  • ロックの同時実行: スレッドが同時にロックできない場合はどうすればよいですか?
  • ロック解除:使用後にロックを解除するにはどうすればいいですか?

簡単に言えば、これらが要素です。抜けている部分があれば追加していただいて構いません。

2ロック記号

ロック フラグには、ロックが成功したかどうかを示すフラグが必要であり、このロック フラグはアトミック性を保証する必要があります。

  • 基礎となる同期メソッドは C++ で実装されています。 ObjectMonitor オブジェクトには、ロックが保持されているかどうかを識別するために使用される _count パラメータがあります。
  • ReentrantLock は AQS に基づいて実装されており、状態はスレッドがロックを保持しているかどうかを示します。 ReentrantReadWriteLock も AQS に基づいて実装されており、状態の上位 16 ビットは読み取りロックを表し、下位 16 ビットは書き込みロックを表します。
  • Redisson は Redis のハッシュ データ構造に基づいて実装されており、ロック キーの存在によってロックされているかどうかが示されます。
  • Curator は ZooKeeper の一時的なシーケンシャル ノードに基づいて実装されます。ロック パスの下にノードが存在するかどうかを判断して、ロックするかどうかを示します。

ロックホルダー3個

  • ロックの保持者は間違いなく現在のスレッドですが、分散ロックでは、サービス間のスレッドの競合を防ぐためのマシンも必要です。
  • synchronized ObjectMonitor オブジェクトでは、_owner はロックを取得したスレッドを参照します。
  • ReentrantLock と ReentrantReadWriteLock は AQS Node ノード内の Thread オブジェクトであり、ロックを取得するスレッドを表すために使用されます。
  • Redisson は、複数のサービス インスタンスがある場合に同時実行の競合を防ぐために、ハッシュ データ構造の field フィールドに UUID:ThreadId を保存します。
  • Curator によって作成された一時的なシーケンシャル ノードには、/locks/lock_01/_c_UUID-lock-0000000000 のような構造を持つ、ロックされたマシンを示す UUID が含まれます。

4 ロックの再入力

ロックを取得したスレッドが再度ロックを取得しようとすると、カウントが保証されます。

  • 同期すると、_count が蓄積され、CAS で更新されます。
  • ReentrantLock は AQS の状態を蓄積し、CAS を更新します。
  • Redisson は Lua スクリプトを使用してハッシュ構造の値を蓄積します。
  • Curator は、再入を示すために Java コード内に AtomicInteger 型の lockCount フィールドを保持します。

5ロック待機

  • 同期された同時ロックが失敗した場合、スレッドはスピンして待機し、バイアス ロック、軽量ロック、重量ロックのロック アップグレード プロセスが実行されます。
  1. 当初はロック解除されていた
  2. バイアス ロック: 同期されたコードのセクションは常に 1 つのスレッドによってアクセスされ、自動的にロックが取得されます。ほとんどの場合、ロックは同じスレッドによって取得されるため、偏ったロックが発生します。目的は、同期されたコード ブロックを 1 つのスレッドのみが実行する場合のパフォーマンスを向上させることです。 JDK 6以降のJVMではデフォルトで有効になっています。オブジェクトヘッダーフラグ(01-ロック解除)バイアスロックフラグ(1-バイアスロック)かどうか
  3. 軽量ロック: ロックがバイアス ロックの場合、他のスレッドによってアクセスされ、バイアス ロックが軽量ロックにアップグレードされます。他のスレッドは、スピンしてロック オブジェクト ヘッダー フラグ 00 を取得しようとします。
  4. 重量ロック: 待機中のスレッドは 1 つだけであり、スレッドはロックを取得するために待機しています。一定数のスピンが発生するか、1 つのスレッドがロックを保持し、他のスレッドがスピンしているときに 3 番目のスレッドが来ると、ロックは重量級のロックにアップグレードされます。オブジェクト ヘッダー フラグ ビット 10
  • ReentrantLock は、前のノードが仮想ヘッド ノードであるかどうかを監視するために AQS 双方向同期キューに配置されます。そうであれば、ロックを取得しようとします。
    • 不公平なロックの場合、新しいスレッドはデフォルトでロックの取得に参加しますが、公平なロックの場合は、最初にキューが空かどうかを確認します。
    • LockSupport.park() メソッドはスピン待機中に使用され、CPU リソースを放棄し、他のスレッドは LockSupport.unpark() を呼び出します。
    • tryLock メソッドを使用して時間を設定できます。ロック取得に失敗した場合、または指定時間内に中断された場合は、ロック取得失敗が返されます。
  • Redisson の同時ロックでは、失敗したスレッドは現在のロックのタイムアウトを取得し、その後、Semaphore の tryAcquire メソッドを通じて一定時間ブロックした後、再度ロックの取得を試みます。
    • 公平ロックは、さらに、スレッド待機キューとして Redis のリスト データ構造を使用し、待機中のスレッドの順序を格納するためにソート セットの順序付きセット データ構造を使用します (スコアはタイムアウトのタイムスタンプです)。
  • Curator 同時ロックは、一時的なシーケンシャル ノードを直接作成し、シーケンシャル ノード内の前のノードを監視します (群集効果を防ぐため)。デフォルトはフェアロックです。

6 ロック解除

  • 同期を手動で解除する必要はありません。
  • ReentrantLock は状態を 0 に減分した後、後続のノードを起動し、後続のノードの一部は LockSupport.unpark(s.thread) を呼び出す必要があります。
  • Redisson はキーを積極的に解放し、直接削除します。タイムアウト解放は、サービスがダウンしており、リースを更新するウォッチドッグが存在しないことを意味します。指定された時間が経過すると、Redis キーは自動的に解放されます。
  • キュレーターは積極的にノードを解放し、削除します。サービスが停止した場合、ノードは自動的に削除されます。

7 結論

この記事では、ロックと分散ロックの基本要素を複数の観点から要約し、分析します。 MySQL などのデータベースに基づくロックも実装の参考として使用できます。

この記事はWeChatの公開アカウント「Programmer Xiaohang」から転載したもので、以下のQRコードからフォローできます。この記事を転載する場合は、プログラマーXiaohangの公式アカウントまでご連絡ください。

<<:  目録: 2021 年に注目を集めるクラウド セキュリティ スタートアップ 10 社

>>:  Linuxシステムの仮想化モデルと障害

推薦する

独占企業百度、破壊企業360、そして新鋭のSogouの今後の戦い

360が検索競争の氷を破った後、百度、360、Sogouの3大検索プレーヤーの戦略的立場と内部の勢い...

Jumei.comがニューヨーク証券取引所に上場、セコイアの帳簿利益は7億ドル

 テンセントテクノロジーニュース、5月16日今夜、国内の化粧品電子商取引プラットフォームJumeiが...

プレスリリースはインターネットのティーザースタイルを利用したイベントマーケティングを活用し、Yuan Fangを有名にした。

マイクロブログが普及している時代では、オンラインジョークは宇宙へのロケットよりも速く広がる可能性があ...

WeChatモーメントにプロモーション広告が表示されない理由

昨日、 WeChat Momentsの広告が出てくるとすぐに、WeChatの友達はみんな興奮していま...

JVMパフォーマンスチューニングを合理的に計画する方法

JVM のパフォーマンス チューニングには多くの側面でのトレードオフが伴い、小さな変更が全体に影響す...

クラウドにデータを保存する前に知っておくべき9つのこと

今、誰もがクラウドコンピューティングについて話しています。現状では、企業はクラウド コンピューティン...

ハッカー集団アノニマスが暴露:FBIはかつてその活動をひそかに組織していた

北京時間7月5日、外国メディアの報道によると、「Wired」誌は最近、ハッカー集団Anonymous...

2021 年のエンタープライズ クラウド戦略の 7 つのトレンド

クラウド コンピューティングは IT ポートフォリオを最新化するための推奨モデルとなり、CIO はア...

dediserve-7.5 ユーロ/KVM/2G メモリ/30g SSD/1.5T トラフィック/香港/シンガポール/12 コンピュータ ルーム

Dediserve は香港とシンガポールにデータセンターを新たにオープンしました。新しいデータセンタ...

SEOトラフィックがさらに略奪され、百度の右入札ポジションが反撃

SEO は、中小企業や個人のウェブマスターにとって、トラフィックを引き付けるために最も一般的に使用さ...

JavaAgent を使用して JVM を騙す

[[435136]] Spring に精通している友人は、AOP をよりよく理解できるはずです。アス...

垂直型電子商取引はO2Oに頼り、非標準製品の収益モデルは多様化している

レッドスターマカリンオンラインモールとQijia Mallの公式トライアルにより、非標準製品(さまざ...

鉄道業界がIoTエッジコンピューティングを活用する方法

鉄道業界は、デジタル化に関して最も複雑な業界の 1 つです。技術的な観点から見ると、既存のシステムを...

独創性は本当に百度の「お気に入り」なのか?

独創性は、ウェブマスターの3分の2の心から消すことのできない影です。今日の大規模ウェブサイトのウェブ...

スラムダンクの桜木から学んでSEOのプロになろう

最近また「スラムダンク」にハマっています。最高です!主人公の桜木花道の、何より目を引く、元気いっぱい...