説明
インタビュアー:ThreadLocalをのあなたの理解のいくつかについて教えてください。
だから我々はそれをどのように答えることができますか????あなたの下でも、考えることができ氷点下熟考してご覧ください。
ThreadLocalのは、任意の場所で使用されますか?
詳細の一部ThreadLocalの!
ThreadLocalのベストプラクティス!
考えます
ThreadLocalのは、任意の場所で使用されますか?
唯一のスレッド上で、その後にThreadLocalについて話していない場合は、どこかの前に使用ディスカッションThreadLocalの下では、聞かせての明確なは、ThreadLocalのは、マルチスレッドのシーンです!!!
クラス2までThreadLocalの誘導を使用します。
任意の所望の場所で得ることができるスレッドコンテキスト情報を保存します!!!
スレッドセーフ、スレッドの安全性による性能損失が同期している必要があります考慮する必要がある特定の状況を避けます!!!
任意の所望の場所で得ることができるスレッドコンテキスト情報を保存します!!!
原因のThreadLocalの性質上、同じスレッドがあなたに取得することができ、その後の場所で、所定の位置に設定されています。スレッドコンテキスト情報を保存するために使用することができます。
そのような後続の会合の列それぞれの要求として、ThreadLocalのセットを用いて行うことができる方法の一般的な、記録任意のIDを取得する取得要求に後続する方法、文字列一緒になるように全体の要求をログに記録する必要があります。
例えば、Springのトランザクション管理は、それぞれが同じDAO接続を得ることができるように、トランザクションのロールバックが提出され、他の操作することができ、ThreadLocalのストレージ接続で、そこにあります。
注: ThreadLocalのこれは、多くの場合、フレームワーク内のいくつかの優れたで便利に使用されている、我々は一般的に少し接触があったが、次のシナリオでは、我々はいくつかの詳細に触れます!
スレッドセーフ、スレッドの安全性による性能損失が同期している必要があります考慮する必要がある特定の状況を避けます!!!
ThreadLocalのは、同時マルチスレッドプログラムの問題を解決するための新しい方法を提供します。ThreadLocalのが、制限があり、のは、アリの仕様を見てみましょう:
ThreadLocalのスレッドでデータを読み書きするために、各スレッドが互いに分離されるように、影響を与えませんThreadLocalのは、問題の共有オブジェクトの更新を解決することはできません!
情報の共有がないので、そこには自然な競争の問題は、このようにいくつかのケースではセキュリティスレッドをパフォーマンスの低下を確実に、ではない、とスレッドの安全性を検討するために例のいくつかを避ける同期させる必要があります!!!
このような場面にも言及したアリの仕様を:
詳細の一部ThreadLocalの!
ThreaLocal使用示例代码:
public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { new Thread(() -> { try { for (int i = 0; i < 100; i++) { threadLocal.set(i); System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { threadLocal.remove(); } }, "threadLocal1").start(); new Thread(() -> { try { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { threadLocal.remove(); } }, "threadLocal2").start(); } }
代码截图:
代码运行结果:
从运行的结果我们可以看到threadLocal1进行set值对threadLocal2并没有任何影响!
Thread、ThreadLocalMap、ThreadLocal总览图
Thread类有属性变量threadLocals (类型是ThreadLocal.ThreadLocalMap),也就是说每个线程有一个自己的ThreadLocalMap ,所以每个线程往这个ThreadLocal中读写隔离的,并且是互相不会影响的。
一个ThreadLocal只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个ThreadLocal!!!
如图:
看到上面的几个图,大概思路应该都清晰了,我们Entry的key指向ThreadLocal用虚线表示弱引用 ,下面我们来看看ThreadLocalMap:
java对象的引用包括 : 强引用,软引用,弱引用,虚引用 。
因为这里涉及到弱引用,简单说明下:
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,该对象仅仅被弱引用关联,那么就会被回收。
当仅仅只有ThreadLocalMap中的Entry的key指向ThreadLocal的时候,ThreadLocal会进行回收的!!!
ThreadLocal被垃圾回收后,在ThreadLocalMap里对应的Entry的键值会变成null,但是Entry是强引用,那么Entry里面存储的Object,并没有办法进行回收,所以ThreadLocalMap 做了一些额外的回收工作。
虽然做了但是也会存在内存泄漏风险(我没有遇到过,网上很多类似场景,所以会提到后面的ThreadLocal最佳实践!!!)
ThreadLocal的最佳实践!
ThreadLocal被垃圾回收后,在ThreadLocalMap里对应的Entry的键值会变成null,但是Entry是强引用,那么Entry里面存储的Object,并没有办法进行回收,所以ThreadLocalMap 做了一些额外的回收工作。
注意: 多くの場合、我々はスレッドプールのシーンを使用している、停止しない、基本的なスレッドを破壊しないでしょう!!!
ライフサイクルはセットは、取得し、その方法には、追加の一定の条件のクリーンアップで呼び出しますが、けれども私たちは、内部のThreadLocalのに非常に大きなターゲットオブジェクトを設定した場合、非常に長いスレッドであるのためThreadLocalMapで、ガベージコレクトされた後にThreadLocal対応におけるキーの入力はヌルになりますが、その後の動作セットに、他の方法を取得することはありません。
だから、ベストプラクティスは、私たちは、クリーンアップするremoveメソッドを呼び出すためのイニシアチブを使用しないでください。
ここでもう一つの利点静的として定義されThreadLocalのが原因のThreadLocalで強い参照に、そしてThreadLocalMapは常に存在し、その後、実行時間が削除され、対応するエントリのキーに適切に配置し、削除することができ、ということです!!!
ベストプラクティスは次のようになります。
試す{//その他のビジネスロジック}最後に{ThreadLocalのオブジェクト.removeは();}このコードをコピー
考えます
インタビューの場合は、上記の内容は、の話することができます置くことができ、個人的に非常に良い感じ、非常に完璧に答えました。しかし、あなたは以下のように答えることができれば、その後、さらに完璧。
ThreadLocalのために、私はネッティーソースを見ていたが、また、FastThreadLocalについて調べるために、一連のコンテンツXXXXX、それがアップグレードです。
私はFastThreadLocalスループットが約3倍jdkThreadLocalで、ローカルでテストしました。