不公平なロックのパフォーマンスが高い理由について話す

Java では、synchronized と ReentrantLock の両方がデフォルトで不公平なロックを使用します。不公平なロックを使用する理由は同じで、どちらもプログラムのパフォーマンスを向上させるためです。では、なぜ不公平なロックによってパフォーマンスが向上するのでしょうか? 次に見てみましょう。

不当なロック

不公平なロック: 各スレッドがロックを取得する順序はランダムであり、先着順の規則には従わないため、どのスレッドも特定の瞬間にロックを直接取得して所有する可能性があります。

これは給油に行くようなものです。ガソリンスタンドに着いたら、目の前で給油している人がいたので、車の中でビブラートをスワイプしました。しばらくすると、前の車が給油を終えて去っていきました。幸せそうにスクロールしています車の中でDouyinについて。しかし、この時、別の車がガソリンスタンドに来て、無料のオイルガンがあることに気づき、レイ兄弟より先にオイルを給油しました。ここのオイルガンはロックになっており、先着順にオイルガンが手に入るわけではなく、不公平なロックとなっています。

フェアロック

公平なロック: 各スレッドがロックを取得する順序は、スレッドがロックにアクセスした順序で取得され、常にフロント スレッドが最初にロックを取得します。

これは、高速道路の料金所を通過するために列に並ぶのと同じで、すべての車が通過するために列に並んで待機し、先頭の車が先に料金所を通過します。

性能比較

公平なロックと不公平なロックのパフォーマンス テスト結果は次のとおりです。次のテスト データは、「Java Concurrent Programming Practice」から取得したものです。

上記の結果から、不公平なロックを使用した場合のスループット率 (単位時間当たりのロックの平均取得成功率) は、公正なロックのスループット率よりも大幅に高いことがわかります。

パフォーマンス分析

上記のテスト データは結果を示していますが、なぜ不公平なロックのパフォーマンスが高いのかは説明されていません。そこで次に、公平なロックと不公平な実行プロセスを分析することで、この質問に対する答えを得ます。

フェアロック実行プロセス

ロックを取得するときは、まずスレッド自体を待機キューの最後尾に追加してスリープし、ロックが不足すると待機キューの先頭のスレッドを起こしてロックの取得を試みます。ロックが使用される順序は、キュー内のシーケンスでもあります。プロセス全体で、スレッドは実行状態からスリープ状態に切り替わり、その後スリープ状態から実行状態に戻りますが、毎回スレッドはスリープして再開し、ユーザー状態からカーネル状態に変換する必要があります。この状態遷移は比較的遅いため、フェア ロックの実行速度は遅くなります。

ユーザーモードとカーネルモード

ユーザー モード: プロセスがユーザー独自のコードを実行しているとき、そのプロセスはユーザー実行状態であると言われます。カーネルモード: タスク(プロセス)がシステムコールを実行し、カーネルコードの実行に入るとき、カーネル実行状態でプロセスを呼び出します。このとき、プロセッサは最も高い特権レベルのカーネルコードで実行されます。 。

なぜカーネルモードとユーザーモードを分けるのでしょうか?

カーネルモードとユーザーモードの区別がないとすると、プログラムはハードウェアリソースの読み書きやメモリの割り当てなどを自由に行うことができるため、プログラマが誤って不適切な内容を書き込んでしまった場合、システムがクラッシュする可能性があるため、書き込まないでください。

ユーザーモードとカーネルモードの区別により、プログラムは特定の操作を行う際に一連の検証・検査を行い、問題がないことを確認した上でリソースを正常に操作できるため、誤って起動してしまう心配がありません。システムが壊れた場合、つまりカーネル モードとユーザー モードを区別すると、プログラムはより安全に実行できますが、同時に 2 つのモード間の切り替えにより一定のパフォーマンスのオーバーヘッドが発生します。

不正ロック実行処理

スレッドがロックを取得すると、最初に CAS を介してロックの取得を試みます。取得が成功すると、スレッドは直接ロックを所有します。ロックの取得に失敗した場合は、待機キューに入り、次のロックを待ちます。ロックの取得を試みます。この利点は、ロックの取得が先着順に従う必要がないため、スレッドのスリープと回復の操作が回避され、プログラムの実行効率が向上することです。

たとえば、ネットワーク転送の業務を行うために小規模なビジネスホールに行った後、私の前で業務を行っている人がいたので、前の女性(業務担当)に「休憩してください」と言いました。 「玄関先で、用事は後で終わりますので、玄関先で電話してください」と言うと、若い女性も優しいのですぐに承諾してくれました。

しかし、用事を終えて女性が私に電話をしてから、私が用事を処理するためにカウンターに戻るまでの間には、一定のアイドル時間があります。これは、キュー内のスレッドが起きるのを待ってから待機するまでのアイドル時間と同じです。執行を再開します。そして、この自由時間に、別の老李が電話代を支払うためにビジネスホールに来ました。老李が電話代を支払った後、私はちょうど戻ってきて、直接ビジネスを処理できます。これは「トリプルウィン」の状況です。

Lao Li が電話料金を支払うために私の後ろに並ぶ必要がなく、私も Lao Li が電話料金を支払うのを待ってから転送プロセスを行う必要がなく、また、営業担当者の業務処理の効率化も実現しました。単位時間内に改善され、早く帰宅できる、いわゆる「トリプル勝利」です。より多くのタスクをより短時間で実行できるのが、不公平なロックの利点です

要約する

この記事では、公平なロックと不公平なロックの定義と実行プロセスを紹介しましたが、両者の実行プロセスの詳細から、不公平なロックは (順次) 順序で実行する必要がないため、後続のロックが実行されることがわかります。ロックの取得を直接試行することもでき、実行をブロックして再開する手順がないため、パフォーマンスが向上します。

おすすめ

転載: blog.csdn.net/Java_LingFeng/article/details/128788311