23

スレッド ローカルで値を設定する:

//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 を実行する複数のスレッドは、同じ A の静的 ThreadLocal 変数 myThreadLocal を更新することになり、それによって ThreadLocal 変数の目的そのものを打ち負かします(ドキュメントで推奨されているのは、ThreadLocal に static を使用することです。)

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

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

4

5 に答える 5

65

ThreadLocalクラスの定義によると

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

つまり、2 つのスレッドt1&t2が実行され、最終的に& (Instances of ) がそれぞれsomeBMethod()設定されます。来て実行すると、 get (以前にそれ自体で設定されています) とgets が取得されます。x1x2Xt1someCMethod()x1t2x2

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

set(currentThread, value) //setting value against that particular thread

get を呼び出すと、

get(currentThread) //getting value for the thread
于 2013-04-27T07:55:39.073 に答える
10

私はJavaのソースコードを勉強し、

  1. java.lang.Thread Class以下のようなインスタンス変数が含まれています。

    ThreadLocal.ThreadLocalMap threadLocals = null;

threadLocalsvariable はstatic ではないため、アプリケーション内のすべてのスレッド (つまり、Thread Class のすべてのインスタンス) には、独自の threadLocals マップのコピーがあります。

  1. このマップのキーは、現在のThreadLocal インスタンスであり、はThreadLocal.set() に引数として渡す値です。

  2. 内部的に値を取得しようとすると、 Current ThreadThreadLocal.get()の ThreadLocalMap から取得されます。

簡単に言えばThreadLocalオブジェクトとの間ではなく、現在のThreadオブジェクトとの間で値を取得および設定しています。

于 2016-09-01T21:56:20.857 に答える
6

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

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

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

于 2013-04-27T07:55:03.840 に答える
1

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

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

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

いいえ。

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

于 2013-04-27T07:53:41.143 に答える
1

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

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

于 2013-04-27T07:53:56.983 に答える