検索
ホームページJava&#&チュートリアルJava マルチスレッドでの ThreadLocal の使用

Java マルチスレッドでの ThreadLocal の使用

Oct 17, 2018 pm 04:21 PM
javaマルチスレッド化

この記事の内容は、Java マルチスレッドでの ThreadLocal の使用に関するものです。必要な方は参考にしていただければ幸いです。

マルチスレッド環境では、synchronized メソッドを使用して HashMap# にアクセスするなど、非スレッドセーフ変数にアクセスするときにスレッド同期を実行する必要があります。 ## 実例。ただし、同期アクセスは同時実行性を低下させ、システムのパフォーマンスに影響を与えます。このとき、各スレッドに独立した変数を割り当てると、非スレッド セーフな変数を非同期的に使用できるようになり、そのような変数をスレッド ローカル変数と呼びます。

名前が示すように、スレッド ローカル変数は、各スレッドが変数の独自の独立したコピーを持ち、通常のローカル変数のように他のスレッドからアクセスできないことを意味します。

Java は言語レベルのスレッドローカル変数を提供していませんが、今回の主役である ThreadLocal クラスのクラスライブラリ内でスレッドローカル変数の機能を提供しています。

ThreadLocal の使用法

Java マルチスレッドでの ThreadLocal の使用
##ThreadLocal の Java8 バージョンには、上の図に示す 4 つがあります。 2 つのパブリック メソッドと 1 つの保護されたメソッドがあります。最初のメソッドは初期値 (デフォルトでは null) を返すために使用されます。 2 番目の静的メソッド withInitial(Supplier extends S>supplier) は Java8 バージョンで新しく追加されたもので、次の 3 つのインスタンス メソッドは非常に単純です。

Java8 より前では、ThreadLocal を使用するときに初期値を設定する場合は、ThreadLocal クラスを継承し、保護された T のinitialValue() メソッドをオーバーライドする必要があります。例:

ThreadLocal<integer> threadLocal = new ThreadLocal<integer>() {
    @Override
    protected Integer initialValue() {
        return 0;
    }
};</integer></integer>
##。 #Java8 版でも利用可能 新しく追加された静的メソッド withInitial(Supplier extends S>supplier) は、初期値を設定するのに非常に便利です。例えば:
ThreadLocal<integer> threadLocal = ThreadLocal.withInitial(() -> 0);

System.out.println(threadLocal.get());
threadLocal.set(16);
System.out.println(threadLocal.get());
threadLocal.remove();
System.out.println(threadLocal.get());

// 同一个线程的输出
0
16
0
Process finished with exit code 0</integer>

ThreadLocal の原理

では、ThreadLocal はスレッドローカル変数の機能をどのように実装するのでしょうか?実際、ThreadLocal の基本原理はそれほど複雑ではありません。 ThreadLocal は内部で静的クラス ThreadLocalMap を定義します。ThreadLocalMap のキーは ThreadLocal オブジェクトです。ただし、この ThreadLocalMap は ThreadLocal クラスに保持されます。 ThreadLocal のソース コードの一部を見てみましょう:

    // ThreadLocal的set方法
    public void set(T value) {
        // 获取当前线程对象
        Thread t = Thread.currentThread();
        // 获取Map
        ThreadLocalMap map = getMap(t);
        if (map != null)
            // 设置值
            map.set(this, value);
        else
            // 初始化Map
            createMap(t, value);
    }
    
    // ThreadLocal的createMap方法
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
    
    // Thread类定义的实例域
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal のコア実装は ThreadLocalMap の実装であり、内部でデータを格納する Entry クラスを宣言していることがわかります:

static class Entry extends WeakReference<threadlocal>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal> k, Object v) {
        super(k);
        value = v;
    }
}</threadlocal>
。 ThreadLocalMap の実装 HashMap の実装と類似点があります。たとえば、配列はデータの保存と自動展開にも使用されます。違いは、ハッシュ アルゴリズムとハッシュ衝突後の処理です。

        // ThreadLocalMap的set方法
        private void set(ThreadLocal> key, Object value) {

            Entry[] tab = table;
            int len = tab.length;
            // 计算在Entry[]中的索引,每个ThreadLocal对象都有一个hash值threadLocalHashCode,每初始化一个ThreadLocal对象,hash值就增加一个固定的大小0x61c88647
            int i = key.threadLocalHashCode & (len-1);

            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal> k = e.get();
                // 如果键已存在就更新值
                if (k == key) {
                    e.value = value;
                    return;
                }
                // 代替无效的键
                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            int sz = ++size;
            if (!cleanSomeSlots(i, sz) && sz >= threshold)
                rehash();
        }
        
        private static int nextIndex(int i, int len) {
            return ((i + 1 ThreadLocalMap が Entry[] 配列をリングとして扱っていることがわかります。計算したインデックスの位置を起点として、インデックスに既にデータがある場合はKeyが同じかどうかを判定し、同じであれば値を更新します。それ以外の場合は、空の位置が見つかるまで待って、そこに値を入れます。値を取得する場合も同様で、計算されたインデックスの位置から開始して、キーが同じであるかどうかを 1 つずつチェックします。ハッシュの衝突が多い場合、パフォーマンスがあまり良くない可能性があります。 <p></p><p>ThreadLocal のアプリケーション</p><p><strong></strong><code><br></code>##ThreadLocal のアプリケーションは非常に広範囲に渡ります。たとえば、Java エンジニアは次のようになります。 ThreadLocal は Spring フレームワークで非スレッドセーフのステートフル オブジェクトをカプセル化するために使用されるため、ほとんどの Bean をシングルトン スコープとして宣言できます。マルチスレッド コードを記述するときは、非スレッド セーフ ステートフル オブジェクトに同期的にアクセスする方が良いのか、それとも ThreadLocal を使用して非スレッド セーフ ステートフル オブジェクトをカプセル化する方が良いのかを考えることもできます。 </p><p><code><span style="font-family: 微软雅黑, Microsoft YaHei;"></span><br></code></p>

以上がJava マルチスレッドでの ThreadLocal の使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はsegmentfault思否で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。