13

静的フィールドは、次のようにクラス名を使用してアクセスされています。

public class Me()
{ 
  public static int a=5;
}

でアクセスできるので、クラスMe.aにアタッチされています。

しかし、私が見ると:

static ThreadLocal<int> _x = new ThreadLocal<int> (() => 3);

各スレッドが の異なるコピーを参照することが保証されます_x

スレッドごとではなく、クラスstaticごとであることがわかりませんでしたか? どのようにして各スレッドに の異なるコピーを与えることができますか?ThreadLocal_x

4

3 に答える 3

12

static はクラスごとであり、スレッドごとではないことがわかりましたか?

はい。インスタンスが、現在のスレッドの Value を検索する をThreadLocal<T>保持しているとします。static Dictionary<Thread, T>

それはおそらく実際にどのように機能するかではありませんが、それがどのように可能であるかを簡単に説明しています。あなたはそれを自分で書くことができます。

したがって、 static はまだ 1 つしかありません_x。ただし_x.Value、現在のスレッドなど、何にでもバインドできます。

于 2012-07-21T11:44:37.100 に答える
8

参照_xは、その指定子に従って、実際にはクラスごとに 1 つになりstaticます。ただし、オブジェクト内の値ではなく、参照のみがすべてのスレッド間で共有されます。にアクセスすると_x.ValueThreadLocal<T>現在のスレッドにストレージを提供するシステム固有のコードが呼び出され、そのスレッド固有のストレージに対して読み取りまたは書き込みが行われます。

于 2012-07-21T11:42:39.570 に答える
4

私の C# はそれほど優れていないので、同じ効果に対する C++ の回答を次に示します。大きな配列を含む架空のクラスを想像してください。

class Foo
{
    int array[HUGE];
    int & get() { return array[this_thread_id()]; }
}:

これで、単一のグローバル (またはクラス静的) オブジェクトを持つことができます。

Foo tlstorage;

あなたが言うどこからでもそれにアクセスするにはtlstorage.get() = 12;。ただし、データは現在のスレッドに「属する」スロットに格納されます。ストレージ全体がグローバルですが、各スレッドに公開されるスライスは 1 つだけです。

C や C++ などの他の言語では、この概念がネイティブでサポートされており、グローバル変数または静的変数を「スレッド ローカル」として修飾すると、コンパイラは自動的に同じ効果をもたらすものを構築します。おそらく C# では、これはライブラリ機能ですが、おそらく組み込みのものにもマップされます。

于 2012-07-21T11:45:14.590 に答える