web-dev-qa-db-ja.com

Java ThreadLocal static?

スレッドローカルでの値の設定:

//Class A holds the static ThreadLocal variable.

    Class A{

    public static ThreadLocal<X> myThreadLocal = new ThreadLocal<X>();             
    ....
    }


//A Class B method sets value in A's static ThreadLocal variable 
    class B{
    {
         public void someBmethod(){
             X x = new X();
             A.myThreadLocal.set(x);
         }
    }


//Class C retrieves the value set in A's Thread Local variable.

    Class C {

    public void someCMethod(){
         X x = A.myThreadLocal.get();
    }
    ...
    }

ケシトン
これがWebアプリケーションであり、スレッドが実行されると仮定します:B.someBMethod、C.someCMethodの順序で。

BのsomeBMethodを実行する複数のスレッドは、最終的に[〜#〜] same [〜#〜] Aの静的ThreadLocal変数myThreadLocalを更新するため、ThreadLocal変数の目的そのものを打ち負かします。 (ドキュメントに従って、ThreadLocalにstaticを使用することをお勧めします。)

CのsomeCMethodは、ThreadLocalから値を取得しているときに、「現在の」スレッドによって設定された値を取得できない場合があります。

ここで何が欠けていますか?

18
Jasper

ThreadLocal クラスの定義に従って

このクラスは、スレッドローカル変数を提供します。これらの変数は、(getまたはsetメソッドを介して)1つにアクセスする各スレッドが、変数の独自の独立して初期化されたコピーを持っているという点で、通常の対応する変数とは異なります。ThreadLocalインスタンスは通常、状態をスレッド(たとえば、ユーザーIDまたはトランザクションID)に関連付けたいクラスのプライベート静的フィールドです。

つまり、2つのスレッド_t1_&_t2_がsomeBMethod()を実行し、最終的に_x1_&_x2_(Xのインスタンス)を設定することになります。それぞれ。 _t1_が来てsomeCMethod()を実行すると、_x1_(setbyそれ自体以前)そして_t2_は_x2_を取得します。

言い換えると、ThreadLocalの静的インスタンスを1つ持つのが安全です。これは、setを呼び出すと内部的にこのようなことを行うためです。

_set(currentThread, value) //setting value against that particular thread
_

getを呼び出すと

_get(currentThread) //getting value for the thread
_
52
sanbhat

Java ソースコード

  1. _Java.lang.Thread Class_には、以下のようにinstance変数が含まれます。

    _ThreadLocal.ThreadLocalMap threadLocals = null;_

threadLocals変数は非静的であるため、アプリケーション内のすべてのスレッド(つまり、スレッドクラスのすべてのインスタンス)には独自のコピー)があります。 threadLocalsマップの。

  1. Keyこのマップの場合current ThreadLocalインスタンス、valueargumentとしてThreadLocalに渡す値です。セットする()。

  2. fetch value as ThreadLocal.get()を実行しようとすると、内部的にはCurrent ThreadのThreadLocalMapからフェッチされます。

簡単に言えば、現在のオブジェクトとの間で値を取得および設定していますスレッドオブジェクト、notから/へThreadLocalオブジェクト。

BのsomeBMethodを実行する複数のスレッドは、同じAの静的ThreadLocal変数myThreadLocalを更新することになります。

はい、それらは同じオブジェクトで動作します。ただし、ThreadLocalが機能する方法は、各スレッドが独自の個別の値を持っていることを理解することが重要です。したがって、10個のスレッドがmyThreadLocalに書き込み、次にmyThreadLocalから読み取る場合、それぞれに正しい(つまり独自の)値が表示されます。

別の言い方をすれば、どのクラスまたはオブジェクトがThreadLocalのインスタンスに書き込むかは重要ではありません。重要なのはthreadであり、そのコンテキストで操作が実行されます。

3
NPE

BのsomeBMethodを実行する複数のスレッドは、同じAの静的ThreadLocal変数myThreadLocalを更新することになります。

いいえ、しません。すべてのスレッドには、タイプXの含まれている変数の独自のインスタンスがあります。

これにより、ThreadLocal変数の目的そのものを打ち負かします

番号。

Javadocをもう一度見てください。

1
user207421

いいえ、彼らはそうしません、それがポイントです。 Javadoc:

これらの変数は、(getまたはsetメソッドを介して)アクセスする各スレッドが、独自に初期化された変数のコピーを持っているという点で、通常の対応する変数とは異なります。 ThreadLocalインスタンスは通常、状態をスレッド(ユーザーIDやトランザクションIDなど)に関連付けたいクラスのプライベート静的フィールドです。

1
NimChimpsky