目次
ソースコードレベルの解析 Synchronized
オブジェクト構造
Monitor オブジェクト
原子性
原子性とは、操作が完了したか、または完了していないことを意味します。半分完了した、つまり操作が完了していないということはありません。可能です。中断されます。
リエントラント ロックの概念は非常に単純です。つまり、スレッドは保持しているオブジェクト ロックを複数回取得できます。この種のロックはリエントラント ロックです。ロックには、同じ数のロックを解放する必要もあります。同期ロックオブジェクトには、ロックを取得した回数、つまりリエントラントの数を記録するためのカウンタがあります。
同期ロックには、ロックなし、バイアスされたロック、軽量ロック、および重量ロックという 4 つの代替アップグレード状態があります。これらの状態は、競合によって徐々にエスカレートします。
ホームページ Java &#&チュートリアル JavaのSynchronizedの原理は何ですか

JavaのSynchronizedの原理は何ですか

May 31, 2023 pm 02:55 PM
java synchronized

    ソースコードレベルの解析 Synchronized

    オブジェクト構造

    Synchronized は Java における暗黙的なロックであり、取得ロックと解放ロックは両方ともこれは暗黙的であり、JVM の操作に完全に委ねられています。Synchronized キーワードを理解する前に、最初に学習すべき知識ポイントは Java オブジェクトの構造です。これは、Synchronized ロックは Java オブジェクトに格納されているためです。Java オブジェクトの構造は次のとおりです。 :

    JavaのSynchronizedの原理は何ですか

    Java オブジェクトは、オブジェクト ヘッダー、インスタンス データ、フィル データの 3 つの部分で構成されていることが明確にわかります。次に、オブジェクト構造の簡単な分析を行います。

    • マークダウン: オブジェクト マーク フィールドは 8 バイトを占め、オブジェクト マークに関する情報を格納するために使用されます。ロックのマークビット. 図から、ハッシュ値、軽量ロックフラグ、バイアスロックフラグなどが存在することがわかります。

    • Klass ポインタ: クラス オブジェクトの型ポインタ。現在のオブジェクトが属するクラスへのポインタです。デフォルトでは、jdk1.8 は圧縮ポインタをオンにし、4 を占有します。圧縮ポインタをオフにします。圧縮ポインタは 8 バイトを占有します。

    • オブジェクトの実際のデータ: この部分にはオブジェクトのすべてのメンバー変数が含まれます。サイズは各メンバー変数によって決まります。たとえば、byte は 1 バイト、int は 4 バイトを占め、等

    • 記入してください: この部分はスペースを補完するためのものであり、プレースホルダーとして機能します。これは、HotSpot 仮想マシンのメモリ管理システムでは、オブジェクトの開始アドレスが次である必要があるためです。は 8 バイトの整数倍であるため、オブジェクト インスタンスが整列していない場合は、パディングする必要があります。

    マークダウンロックタイプのマークには、ロックなし、偏りロック、軽量ロック、重量ロック、GCマークの計5種類があることが分かります。したがって、2 ビットのマークのみを使用すると完全に表現できないため、バイアス ロック マークが導入されます。つまり、001 はロックなし、101 はバイアス ロックを意味します。

    Monitor オブジェクト

    オブジェクト構造は上で紹介したとおりで、Mark-down にさまざまなロック情報が格納されることがわかります。ロック状態がヘビーウェイト ロック (10) の場合、マークダウンは、Monitor オブジェクトへのポインターを保存します。この Monitor オブジェクトは、モニター ロックとも呼ばれます。

    同期の動作メカニズムは、JVM が共有オブジェクト内のさまざまな競合状況を検出すると、適切なロック実装に自動的に切り替えます。この切り替えがロックのアップグレードまたはダウングレードです。 (ロックはアップグレードのみ可能でダウングレードはできないと多くの場所で述べられています。実際、この記述は間違いです。書籍「The Art of Java Concurrent Programming」では、バイアスされたロックの場合、ロックにダウングレードできると記載されています。フリー状態、およびバイアスされたロックの取り消しと呼ばれます)。

    現在、バイアス ロック、軽量ロック、重量ロックという 3 つの異なるモニター実装があります。スレッドがモニターを保持すると、ロックを取得します。

    Monitor in Java は、C の ObjectMonitor に基づいて実装されています。その主なメンバーは次のとおりです:

    • _owner: ObjectMonitor オブジェクトを保持するスレッドへのポイント

    • #_WaitSet: スレッド キューを待機状態に保存します。つまり、wait() メソッドを呼び出すスレッドです。

    • ##_EntryList: スレッド キューを待機中のロックに保存します。ブロック状態
    • _count: _WaitSet _EntryList 内のノード数のおおよその合計
    • _cxq: ロックを競合する複数のスレッドが最初に保存しますこの一方向のリンク リスト
    • _recursions: 再エントリの数を記録します
    • _object: 保存されたモニター オブジェクト
    • Get Monitor オブジェクトのスレッドが _owner 領域に入ると、_count は 1 になります。スレッドが wait() メソッドを呼び出すと、Monitor オブジェクトが解放され (ロックが解除され)、_owner が元の状態に戻ります。空および_count-1。この時点で、スレッドは _WaitSet キューに入り、起動されるのを待ちます。

    上記の説明からわかるように、synchronized キーワードを使用してロックを取得する鍵は、各オブジェクトのオブジェクト ヘッダーにあります。これは、synchronized() 括弧内に格納されているオブジェクトがロックを取得できる理由も説明しています。 特徴。

    同期機能

    原子性

    原子性とは、操作が完了したか、または完了していないことを意味します。半分完了した、つまり操作が完了していないということはありません。可能です。中断されます。

    synchronized は、同時に 1 つのスレッドだけがロックを取得し、コード ブロックに入ってコードを実行することを保証します。これが理解できない場合は、次のシーンを想像してください。トイレは1つのピットで、複数人が一緒にトイレに行くという非文明的な現象を防ぐために、トイレにも施錠されています。トイレを使用する人は全員、トイレ管理者に支払いをしなければなりません。支払い後、トイレに行く前にロックを受け取ることができます。トイレを使用した後は、トイレ管理者に鍵を返却することができます。同期はトイレ管理者なので、一度に 1 人だけが鍵を取得でき、トイレ使用後は全員が鍵を返却する必要があります。

    次に、次の同期追加メソッドを参照してください:

    public static void add() {
        synchronized (Demo.class) {
            counter++;
        }
    }
    ログイン後にコピー

    それをデコンパイルしてコードを表示します:

    javap -v -p Demo

    public static void add();
        descriptor: ()V
        flags: ACC_PUBLIC, ACC_STATIC , ACC_SYNCHRONIZED
        Code:
          stack=2, locals=2, args_size=0
             0: ldc           #12                 // class
             2: dup
             3: astore_0
             4: monitorenter
             5: getstatic     #10                 // Field counter:I
             8: iconst_1
             9: iadd
            10: putstatic     #10                 // Field counter:I
            13: aload_0
            14: monitorexit
            15: goto          23
            18: astore_1
            19: aload_0
            20: monitorexit
            21: aload_1
            22: athrow
            23: return
          Exception table:
    ログイン後にコピー

    次のことができます。明らかにモニターに関連する 2 つの命令があることに注意してください:

    • #monitorenter: 同期フラグ ACC_SYNCHRONIZED があると判断した後、最初にこのメソッドに入ったスレッドが最初に Monitor の所有者になります。このときのカウンタは 1

    • monitorexit: 実行時、終了後、カウンタは -1 になり、0 に戻り、他の開始スレッドによって取得されます。

    Visibility

    Visibility は、を参照します。複数のスレッドが同じ変数にアクセスするとき スレッドがこの変数の値を変更すると、他のスレッドはそれを即座に感知し、変更された値を確認できます。スレッドの可視性は JMM と密接に関係しています。次の記事では、volatile キーワードを使用して可視性を実現する方法を検討します。

    そして、Synchronized にはロックとロックの解放に関する次のセマンティクスがあるため、可視性があります:

    • スレッドがロックする前に、メインメモリから共有変数の最新の値を読み取るために、作業メモリ内の共有変数の値をクリアする必要があります。

    • スレッドがロックを解放すると、共有変数の値がメイン メモリに更新される必要があります。

    • synchronized の可視性は、オペレーティング システムのカーネル ミューテックスの実装に依存します。これは、JVM のロックとロック解除に相当します。コード ブロックを終了するときは、共有変数を更新する必要があります。この点 volatile キーワードとは異なり、volatile キーワードの可視性はメモリ バリア (メモリ バリアとも呼ばれます) に依存します。

    順序性

    as-if-serial は、コンパイラとプロセッサがパフォーマンスの最適化のために命令をどのように並べ替えても、それが保証される必要があることを保証するためのものです。シングルスレッド

    での実行結果の正確性。つまり: このスレッド内で観察すると、すべての操作は順序どおりですあるスレッド内の別のスレッドを観察すると、すべての操作は順序どおりではありませんここでの順序付けは volatile とは異なることに注意してください。命令の並べ替えを防ぐために volatile ではありません。

    リエントラント ロック

    リエントラント ロックの概念は非常に単純です。つまり、スレッドは保持しているオブジェクト ロックを複数回取得できます。この種のロックはリエントラント ロックです。ロックには、同じ数のロックを解放する必要もあります。同期ロックオブジェクトには、ロックを取得した回数、つまりリエントラントの数を記録するためのカウンタがあります。

    ロック アップグレードのプロセス

    同期ロックには、ロックなし、バイアスされたロック、軽量ロック、および重量ロックという 4 つの代替アップグレード状態があります。これらの状態は、競合によって徐々にエスカレートします。

    完全なロックアップグレード図は後で追加されます

    以上がJavaのSynchronizedの原理は何ですかの詳細内容です。詳細については、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 プログラミング Oct 13, 2024 pm 01:32 PM

    Java は、初心者と経験豊富な開発者の両方が学習できる人気のあるプログラミング言語です。このチュートリアルは基本的な概念から始まり、高度なトピックに進みます。 Java Development Kit をインストールしたら、簡単な「Hello, World!」プログラムを作成してプログラミングを練習できます。コードを理解したら、コマンド プロンプトを使用してプログラムをコンパイルして実行すると、コンソールに「Hello, World!」と出力されます。 Java の学習はプログラミングの旅の始まりであり、習熟が深まるにつれて、より複雑なアプリケーションを作成できるようになります。

    See all articles