InheritableThreadLocalの使用と最もシンプルでわかりやすいソースコード解析

ThreadLocal の基本的な使い方とソースコード

ThreadLocal に関する知識ポイントについては、別のブログを読む必要があります:
ThreadLocal の簡単な使い方とソース コード

InheritableThreadLocal の基本的な使用法

ThreadLocal を理解した後、次の例を見てみましょう。
ここに画像の説明を挿入
ThreadLocal の欠点がわかります: 親スレッドと子スレッドはデータを共有できません。
次に、例を変更しましょう。 この問題を完全に解決するには、InheritableThreadLocal を使用します。
ここに画像の説明を挿入

ソースコード分析:

ここで、立ち止まって考えてみてください:
(1) 子スレッドが親スレッドによって設定されたパラメータを取得できるようにするにはどうすればよいでしょうか。
(2) どこに置かれていますか? どうやって取り出すのでしょうか?
よりよく理解するには、これら 2 つの質問を見る必要があります

1:どうやって置くの?

ここでは、親スレッドによって作成された子スレッド、つまり親スレッドと子スレッドを区別することに細心の注意を払う必要があります。最初のステップは、
パラメータ値がどこに保存されているかを全員に直接伝えることです。
ここに画像の説明を挿入
ここでは、単純に理解できます。場所は異なりますが、ThreadLocal 値が対応するスレッドに格納されることは誰もが知っているため、本当に重要なのは、スレッドの初期化作成部分でこれら 2 つの値をどのように設定するかによって決まります。

スレッドの初期化から始めましょう。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

⚠️ ここでデフォルトの true を初期化することが非常に重要であることに注意してください。このステップは次のステップで判断されます。

ここに画像の説明を挿入
少し下に、別のロジックがあります:
ここに画像の説明を挿入
判断: 現在の親スレッドの継承可能なThreadLocals が設定されている場合、createInheritedMap メソッドを通じて ThreadLocalMap を返し、それを現在作成中の子スレッド クラスに格納します。これ?こうすることで、子スレッドを作成している親スレッドのinheritableThreadLocalsの値を、作成中の子スレッドのinheritableThreadLocalsに代入できるため、このラウンドでは、誰が現在の作成者で誰が作成中であるかを区別する必要があります。引き続き
createInheritedMap メソッドを参照してください:
ここに画像の説明を挿入
このメソッドは新しい ThreadLocalMap を作成し、それを返すことがわかります。ソース コードには、返されたマップが親スレッドに関連付けられていることが示されています。

入手方法は?

これは比較的単純で、inheritableThreadLocals がメソッドを書き換えます。
ここに画像の説明を挿入

返されるのは t.threadLocal ではなく t.inheritableThreadLocals であり、この getMap メソッドは正確に対応するスレッドの ThreadLocalMap メソッドを取得し、さらにマップから Value を取得してから戻ります。ここまででショー全体が終了します。
ここに画像の説明を挿入
ここに画像の説明を挿入

糸溜まりで使用するピット⚠️

上記のソース コード分析によると、結論を引き出すのは難しくありません。親スレッドの継承可能なThreadLocals 変数を継承するには、初期化された子スレッドである必要があります。スレッド プールの場合は、それが理由です。スレッドを多重化すると、init がないため、当然のことながら、再割り当ての方法は、子スレッドから取得したパラメータと、親スレッドによって InheritableThreadLocal に詰め込まれたパラメータの間に不一致が発生します。

おすすめ

転載: blog.csdn.net/whiteBearClimb/article/details/123063900