1

素朴に、私は ThreadLocal が値型への Thread の WeakHashMap のようなものであると予想していました。そのため、 ThreadLocal の値が実際には Thread のマップに保存されていることを知ったとき、私は少し戸惑いました。なぜそのようにされたのですか?値が ThreadLocal 自体に保存されている場合、ThreadLocal に関連するリソース リークは発生しないと思います。

明確化:私は次のようなことを考えていました

public class AlternativeThreadLocal<T> { 
    private final Map<Thread, T> values = 
        Collections.synchronizedMap(new WeakHashMap<Thread, T>());
    public void set(T value) { values.put(Thread.currentThread(), value); }
    public T get() { return values.get(Thread.currentThread());}    
}

私が見る限り、これは、値が何らかの形で ThreadLocal 自体を強く参照している場合、スレッドが死ぬまで ThreadLocal も残りの値もガベージコレクションされないという奇妙な問題を防ぎます。(おそらく、これの最も悪質な形式は、値が参照するクラスの静的変数が ThreadLocal である場合に発生します。オブジェクトもそのクラスも収集できないため、アプリケーション サーバーの再デプロイで大きなリソース リークが発生します。)

4

4 に答える 4

8

質問するだけで悟りを得られることもあります。:-) これで、考えられる答えが 1 つあります。それは、スレッド セーフです。値を含むマップが Thread オブジェクトにある場合、新しい値の挿入は自明にスレッドセーフです。マップが ThreadLocal 上にある場合、通常の同時実行性の問題が発生し、速度が低下する可能性があります。(もちろん、同期の代わりに ReadWriteLock を使用しますが、問題は残ります。)

于 2009-12-01T21:32:48.457 に答える
4

ThreadLocalリークの問題を誤解しているようです。ThreadLocalリークは、スレッドプールなどで同じスレッドが繰り返し使用され、使用の合間にThreadLocal状態がクリアされない場合に発生します。スレッド自体を除いてThreadLocalマップを参照するものはないため、スレッドが破棄されたときにThreadLocalが残っている結果ではありません。

スレッドからスレッドローカルオブジェクトへの参照マップが弱くても、スレッドはスレッドプールにまだ存在するため、スレッドローカルリークの問題を防ぐことはできません。そのため、スレッドがプールから再利用される場合、スレッドローカルオブジェクトは収集の対象になりません。リークを回避するには、ThreadLocalを手動でクリアする必要があります。

あなたがあなたの答えで言ったように、同時実行制御はスレッドごとに単一のインスタンスであるThreadLocalMapで単純化されています。また、あるスレッドが別のスレッドのローカルオブジェクトにアクセスできなくなります。これは、ThreadLocalオブジェクトが提案したマップ上のAPIを公開している場合には当てはまらない可能性があります。

于 2009-12-01T21:38:44.667 に答える
0

数年前、Sun がスレッドローカルの実装を現在の形式に変更したことを覚えています。それがどのバージョンで、古い impl がどのようなものだったかは覚えていません。

とにかく、各スレッドがスロットを持つ必要がある変数の場合、Thread は自然に選択されるコンテナーです。可能であれば、スレッド ローカル変数を Thread クラスのメンバーとして直接追加することもできます。

于 2009-12-01T22:07:39.723 に答える
0

なぜMapオンになるのThreadLocalですか?それはあまり意味がありません。ThreadLocalつまり、ThreadLocal 内のオブジェクトへの s のマップでしょうか?

Threads からオブジェクトへのマップである単純な理由は次のとおりです。

  1. これは実装の詳細です。つまり、Mapまったく公開されていません。
  2. 現在のスレッドを把握するのは常に簡単です ( を使用Thread.currentThread())。

また、ThreadLocal は、それを使用する Thread ごとに異なる値を格納できるため、Thread に基づいていることは理にかなっていますね。

于 2009-12-01T22:51:54.120 に答える