ホームページ  >  記事  >  Java  >  スレッドローカルとは何ですか? ThreadLocalの原理分析

スレッドローカルとは何ですか? ThreadLocalの原理分析

不言
不言転載
2018-10-11 16:37:3810842ブラウズ

この記事では、ThreadLocal とは何ですか? ThreadLocal の原理分析には一定の参考値がありますので、お役に立てれば幸いです。

1. ThreadLocal とは何ですか?

ThreadLocal はスレッド ローカル変数を提供します。これらの変数は、(get メソッドまたは set メソッドを通じて) このような変数にアクセスする各スレッドが、独自の独立して初期化された変数のコピーを持つという点で通常の変数とは異なります。

ThreadLocal インスタンスは通常、状態をスレッド (ユーザー ID やトランザクション ID など) に関連付けたいクラスのプライベート静的フィールドです。

(ナレーション: この文章は 3 つの意味を表しています。

1. ThreadLocal は変数タイプであり、これを「スレッド ローカル変数」と呼びます。

2. 各スレッドは、この変数のコピーはスレッドに対してプライベートです。

3. ThreadLocal 型の変数は通常、 private static)

で変更されます。たとえば、次の例ではこれです。クラスはスレッドごとに一意の識別子を生成します。スレッドの ID は、初めて ThreadId.get() メソッドを呼び出すときに指定されます。

package com.cjs.example;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
    private static final AtomicInteger nextId = new AtomicInteger(0);
    private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return nextId.getAndIncrement();
        }
    };
    public static int get() {
        return threadId.get();
    }
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getId());
                }
            }).start();
        }
    }
}

2. ThreadLocal のメイン操作

/**
 * 返回当前线程对ThreadLocal变量的“初始值”
 * 这个方法将在线程第一次访问变量(通过调用get方法)时被调用,如果之前已经调用过了就不会再调了
 *
 * @return the initial value for this thread-local
 */
protected T initialValue() {
    return null;
}

/**
 * 设置当前线程的ThreadLocal变量的副本为指定的值
 *
 * @param value the value to be stored in the current thread&#39;s copy of this thread-local.
 */
public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
/**
 * 返回当前线程的ThreadLocal变量副本的值
 *
 * @return the current thread&#39;s value of this thread-local
 */
public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

/**
 * 删除当前线程的ThreadLocal变量副本的值
 */
public void remove() {
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        m.remove(this);
}

3. ソース コードを読む

3.1. メソッドの設定

#ご覧のとおり、ThreadLocalMap の最下層は配列であり、配列内の要素の型は Entry 型です。

set 操作は、ThreadLocal のメンバー変数 threadLocals に値を設定することです。現在のスレッドの ThreadLocalMap タイプ。キーは this で、値は指定したものです。

ここで渡されるこれは、ThreadLocal タイプの変数 (またはオブジェクト) を表すことに注意してください。各スレッドは ThreadLocal.ThreadLocalMap タイプのオブジェクトを維持し、設定操作では実際に ThreadLocal 変数をキーとして使用し、指定した値を値として使用し、最後にこのキーと値のペアを Entry オブジェクトにカプセル化して ThreadLocal に置きます。スレッドの .ThreadLocalMap オブジェクト。スレッド内の各 ThreadLocal 変数は、ThreadLocal.ThreadLocalMap オブジェクトのエントリです。各 ThreadLocal 変数は ThreadLocal.ThreadLocalMap の要素に対応するため、これらの要素は読み取り、書き込み、削除が可能です。

3.2. get メソッド

get() メソッドは、ThreadLocal.ThreadLocalMap オブジェクトから対応する ThreadLocal 変数を取得します。現在のスレッド 対応する値

同様に、remove() メソッドはこの値をクリアします。

グラフで表すと、おそらく次のようになります:

または次のようにします:

4. ThreadLocal の使用シナリオ

スレッドのライフサイクル中に値を転送する

最後に、すべて ThreadLocalMap の功績です

以上がスレッドローカルとは何ですか? ThreadLocalの原理分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。