Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析
偏ったロック
#バイアスされたロックは本質的に「遅延ロック」と同等です。ロックしない場合はロックしないでください。不必要なロックのオーバーヘッドを避けるようにしてください。ただし、それでも
バイアスされたロックは実際のロックではなく、ロックのオブジェクト ヘッダーにマークを記録するだけです (ロックが行われているスレッドを記録します)。他のスレッドがロックの競合に参加していない場合、ロック操作は実際には実行されないため、プログラムのオーバーヘッドが削減されます。他のスレッドが実際に関与すると、スレッド競合が発生し、偏ったロック状態がキャンセルされ、軽量モードに入ります。ロック状態
軽量ロック
他のスレッドが競合に参加すると、偏ったロック状態が排除され、軽量ロック状態ステータス (適応スピン ロック) に入ります。ここでの軽量ロックは CAS を通じて実装されます。 .
CAS を介してメモリの一部を確認して更新します (スレッドによって参照される null => など)
更新が成功した場合、ロックは成功したとみなされます。
更新に失敗した場合は、ロックが占有されているとみなされ、(CPU を放棄せずに) スピン待機が継続されます。
スピン操作は CPU をアイドリング状態にしておくのは CPU の無駄です。したがって、ここでのスピンは永久に継続するわけではなく、特定の時間/再試行回数に達するとスピンが停止します。これはいわゆる「適応型」です
ヘビーウェイト ロック
If競合が激しくなり、スピンがすぐにロック ステータスを取得できなくなると、ヘビーウェイト ロックに拡張されます。ここでのヘビーウェイト ロックとは、カーネルによって提供されるミューテックスの使用を指します。
ロック操作を実行するには, まずカーネル状態に入ります。
現在のロックがカーネル状態で占有されているかどうかを確認します。
ロックが占有されていない場合、ロックは成功し、切り替えが実行されます。ユーザー モードへ。
ロックが占有されている場合、ロックは失敗します。このとき、スレッドはロックの待機キューに入り、ハングします。オペレーティング システムによって起動されるのを待っています。
一連の時間が経過すると、ロックは他のスレッドによって解放され、オペレーティング システムも中断されたスレッドを記憶したため、スレッドを起動してロックを再取得しようとしました
3. その他の最適化操作
ロックの削除
コンパイラ JVM は、ロックを削除できるかどうかを判断します。削除できる場合は、直接削除されます。
一部のアプリケーションでは、コード内で synchronized が使用されていますが、実際にはマルチスレッド環境 (StringBuffer など) では使用されません)
StringBuffer sb = new StringBuffer(); sb.append("a"); sb.append("b"); sb.append("c"); sb.append("d");
現時点では、各追加呼び出しにはロックとロック解除が含まれますが、このコードが単一のスレッドでのみ実行される場合、これらはロックとロック解除の操作は必要なく、一部のリソースのオーバーヘッドが無駄になります。
ロックの粗大化
ロジックの一部で複数のロックとロック解除が発生した場合、コンパイラ JVM は自動的にロックを粗密化します。 .
リーダー、部下に仕事のタスクを説明してください。
方法 1:
電話をかけ、タスク 1 を説明し、電話を切ります。電話.
電話をかけ、タスク 2 を説明し、電話を切ります。
電話をかけ、タスク 3 を説明し、電話を切ります
方法 2:
電話をかけ、タスク 1、タスク 2、タスク 3 を与え、電話を切ります
4. 呼び出し可能なインターフェイス
呼び出し可能とは
Callable はインターフェイスです。スレッドに「戻り値」をカプセル化するのと同じです。プログラマにとって、マルチスレッドを使用して結果を計算するのに便利です。
Callable 和 Runnable 相对, 都是描述一个 "任务". Callable 描述的是带有返回值的任务, Runnable 描述的是不带返回值的任务.Callable 通常需要搭配 FutureTask 来使用. FutureTask 用来保存 Callable 的返回结果. 因为 Callable 往往是在另一个线程中执行的, 啥时候执行完并不确定. FutureTask 就可以负责这个等待结果出来的工作.
代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 不使用 Callable 版本
public class Text { static class Result{ public int sum = 0; public Object locker = new Object(); } public static void main(String[] args) throws InterruptedException { Result result = new Result(); Thread t = new Thread(){ @Override public void run() { int sum = 0; for (int i = 0; i <=10000; i++){ sum += i; } result.sum = sum; synchronized (result.locker){ result.locker.notify(); } } }; t.start(); synchronized (result.locker){ while (result.sum == 0){ result.locker.wait(); } } System.out.println(result.sum); } }
代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 使用 Callable 版本
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class Text1 { public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i <=1000; i++){ sum += i; } return sum; } }; //由于Thread不能直接传一个callable实例,就需要一个辅助类来包装 FutureTask<Integer> futureTask = new FutureTask<>(callable); Thread t = new Thread(futureTask); t.start(); //尝试在主线程获取结果 //如果FutureTask中的结果还没生成。此时就会阻塞等待 //一直等到最终的线程把这个结果算出来,get返回 Integer result = futureTask.get(); System.out.println(result); } }
以上がJava での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4
