ホームページ >Java >&#&チュートリアル >ThreadLocal 原理の簡単な分析
ThreadLocal はスレッド ローカル変数を意味します。では、スレッドローカル変数とは何でしょうか?これは何の役に立つのですか?面接で聞かれたのに何も言えなかったということでしょうか?今日は、この製品のソース コードを見て、その機能を基本的に理解しましょう。
Thread、ThreadLocalMap、および Entry の関係
実際、彼のソース コード実装を研究したところ、実際にはそうではありませんでした。想像通り複雑ですが、要点は次のとおりです:
1. Java は Thread.currentThread() を通じて現在の Thread インスタンス オブジェクトを取得できます。 Thread オブジェクトのインスタンスを取得できたので、Thread オブジェクトに値を設定するなど、インスタンス (プロパティ) を操作できるようになります。
2. 各 Thread オブジェクトには、Entries の配列を持つ ThradLocalMap インスタンスがあります。Entry オブジェクトには、値と ThreadLocal への弱参照という 2 つの主な属性があります。値属性は値の設定です。現在のスレッドによって定義され、ThreadLocal のコア属性でもあります。
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
Entry は WeakReference から継承しており、そのキーは ThreadLocal オブジェクトであることに注意してください。 (図 1)
2 つの知識ポイント 1 と 2 を組み合わせると、Thread オブジェクトを取得した後、現在のスレッド オブジェクトの ThreadLocalMap オブジェクトを制御できることがわかります。 ThreadLocalMap の Entry の value 属性に保存したい値を指定すると、Thread、ThreadLocalMap、value の関係は次の図で表すことができます (図 2)。
#上の図から次の結論を導き出すことができます。Thread オブジェクトは ThreadLocalMap オブジェクトを保持し、次に ThreadLoalMap オブジェクトには複数の ThreadLlocal オブジェクトと ThreadLocal オブジェクトが配置されているスレッドの値が含まれます。 ! !簡単に言うと、Thread オブジェクトは複数の ThreadLocal オブジェクトの変数値を保持できます。それでは、ThreadLocal と Thread の間にはどのような関係があるのでしょうか。両者はどのようにして値を読み取ることができるでしょうか?以下はソースコードに基づいた簡単な分析です。
ThreadLocal と Thread の関係まず ThreadLocal の set メソッドを見てください: public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程持有的ThreadLocalMap
ThreadLocal.ThreadLocalMap map = getMap(t);
//将value设置给threadlocalMap
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
set メソッドは非常に論理的で単純です (j上の図 2 と組み合わせたもの (よりよく理解するために参照してください):
1. currentThread メソッドを通じて現在の Thread オブジェクトを取得します
2. 現在の Thread オブジェクトの ThreadLoalMap オブジェクトを取得します
3. ThreadLocal オブジェクトと一緒に値を追加する Entry オブジェクトを自分で作成し、
ThreadLoalMap の Entry 型配列に保存します。
ThreadLocal の get メソッドを見てみましょう:public T get() { //获取当前线程 Thread t = Thread.currentThread(); //获取当前线程的ThreadLocalMap对象 ThreadLocalMap map = getMap(t); if (map != null) { //获取与ThreadLocal对象想关联的value ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") //获取值 T result = (T)e.value; return result; } } //为空返回初始化值 return setInitialValue(); }get の全体的なロジックは開発可能であり、非常に単純です:
2. 現在の Thread オブジェクトの ThreadLocalMap オブジェクトを取得します
3. ThreadLocalMap から ThreadLocal に関連付けられた Entry オブジェクトを取得します (具体的には ThreadLocal を鍵。
4. 手順 3 でエントリの value 属性を取得し、それを返します。
get メソッドと set メソッドを全体的に観察すると、次の結論を導き出すことができます: ThreadLocal オブジェクトの set メソッドの呼び出しは、ThreadLocal オブジェクトの ThreadLocalMap に値を追加することです。 ThreadLocalオブジェクトはThreadオブジェクトのThreadLocalMapから値を取得します。中心となるのは、Thread オブジェクトの ThreadLocalMap オブジェクトを操作して、値の読み取りと書き込みを行うことです。原理はとてもシンプルです。
それでは、異なるスレッドにある異なる ThreadLocal オブジェクトと、他のスレッドに値を保存することとの間にはどのような関係があるのでしょうか?これは次の図で明確に説明できます。
ThreadLocal の使用例
Android には A しかないことがわかっています。 Looper オブジェクトはどのように作られるのでしょうか?役割を果たすのは ThreadLocal です。Looper の prepare メソッドを見てください: //定义一个静态的ThreadLocal变量
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static void prepare(boolean quitAllowed) {
//一个Thread只能关联一个Looper对象
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
準備メソッドを観察することでわかります。まず、sThreadLocal の get メソッドを使用して、現在のスレッドが既に Looper を所有しているかどうかを確認します。オブジェクト。そうである場合は、例外をスローします。 ; 現在のスレッドが Looper オブジェクトを設定していない場合は、ThreadLocal の set メソッドを呼び出して Looper オブジェクトを初期化し、それを現在のスレッドに渡します:
sThreadLocal.set(new Looper(quitAllowed));
これにより、次のことが保証されます。スレッドには Looper オブジェクトが 1 つだけあります。
ここまでで、ThreadLocal の原理は大まかに解析できましたが、内部的な設定方法や取得方法については、ブロガーは ThreadLocal の動作理由や利用シーンを理解する必要がないため、あまり詳細な解析は行っていません。 。 それでおしまい。
以上がThreadLocal 原理の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。