目次
CAS を介してメモリの一部を確認して更新します (スレッドによって参照される null => など)
ロック操作を実行するには, まずカーネル状態に入ります。
コンパイラ JVM は、ロックを削除できるかどうかを判断します。削除できる場合は、直接削除されます。
一部のアプリケーションでは、コード内で synchronized が使用されていますが、実際にはマルチスレッド環境 (StringBuffer など) では使用されません)
Callable はインターフェイスです。スレッドに「戻り値」をカプセル化するのと同じです。プログラマにとって、マルチスレッドを使用して結果を計算するのに便利です。
ホームページ Java &#&チュートリアル Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析

Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析

Apr 21, 2023 am 08:04 AM
java synchronized callable

    1. 基本機能

    1. 楽観的ロックから始まり、ロック競合が多発する場合は悲観的ロックに変換されます。 ## 2. 軽量ロックの実装から始めます。ロックが長時間保持されると、重量ロックに変換されます。

    3. 軽量ロックを実装する場合は、スピン ロックが使用される可能性が最も高くなります。戦略

    4. それは不公平なロックです

    5. それは再入可能なロックです

    6. 読み取り/書き込みロックではありません

    2. ロック プロセス

    JVM は、同期ロックをロックなし、バイアスされたロック、軽量ロック、および重量ロックの状態に分割します。状況に応じて順次バージョンアップしてまいります。

    偏ったロック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 は自動的にロックを粗密化します。 .

    リーダー、部下に仕事のタスクを説明してください。

    Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析方法 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 サイトの他の関連記事を参照してください。

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

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

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

    AI Clothes Remover

    AI Clothes Remover

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

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

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

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

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

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

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

    Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

    Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

    Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

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

    ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

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

    Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

    Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

    Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

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

    Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

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

    Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

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

    カプセルの量を見つけるためのJavaプログラム カプセルの量を見つけるためのJavaプログラム Feb 07, 2025 am 11:37 AM

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

    See all articles