[ThreadStatic]
ThreadLocal<T>
일반 을 사용 하는 동안 속성을 사용 하여 정의됩니다 . 다른 디자인 솔루션을 선택한 이유는 무엇입니까? 이 경우 속성에 대한 일반 사용의 장점과 단점은 무엇입니까?
답변
댓글에 언급 된 블로그 게시물이 명시 적이 지 않지만 매우 중요하다고 생각되는 [ThreadStatic]
것은 모든 스레드에 대해 자동으로 초기화되지 않는다는 것입니다. 예를 들어 다음이 있다고 가정합니다.
[ThreadStatic]
private static int Foo = 42;
이 사용하는 첫 번째 스레드가 볼 수 Foo
에 초기화 42
. 그러나 후속 스레드는 그렇지 않습니다. 이니셜 라이저는 첫 번째 스레드에서만 작동합니다. 따라서 초기화되었는지 확인하기 위해 코드를 작성해야합니다.
ThreadLocal<T>
Reed의 블로그에 표시된대로 항목에 처음 액세스하기 전에 실행되는 초기화 함수를 제공하여 해당 문제를 해결합니다.
제 생각에는, 사용에 아무런 장점이없는 [ThreadStatic]
대신 ThreadLocal<T>
.
답변
ThreadStatic 첫 번째 스레드에서만 초기화하고 ThreadLocal은 각 스레드에 대해 초기화합니다. 다음은 간단한 데모입니다.
public static ThreadLocal<int> _threadlocal =
new ThreadLocal<int>(() =>
{
return Thread.CurrentThread.ManagedThreadId;
});
public static void Main()
{
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("First Thread: {0}", x);
}
}).Start();
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("Second Thread: {0}", x);
}
}).Start();
Console.ReadKey();
}
답변
ThreadStatic의 기본 개념 은 각 스레드에 대해 별도 의 변수 복사본 을 유지하는 것 입니다.
class Program
{
[ThreadStatic]
static int value = 10;
static void Main(string[] args)
{
value = 25;
Task t1 = Task.Run(() =>
{
value++;
Console.WriteLine("T1: " + value);
});
Task t2 = Task.Run(() =>
{
value++;
Console.WriteLine("T2: " + value);
});
Task t3 = Task.Run(() =>
{
value++;
Console.WriteLine("T3: " + value);
});
Console.WriteLine("Main Thread : " + value);
Task.WaitAll(t1, t2, t3);
Console.ReadKey();
}
}
위의 스 니펫 value
에는 주 스레드를 포함하여 각 스레드 에 대한 별도의 복사본이 있습니다.
따라서 ThreadStatic 변수는 생성 된 스레드를 제외한 다른 스레드에서 기본값으로 초기화됩니다.
우리 자신의 방식으로 각 스레드에서 변수를 초기화하려면 ThreadLocal을 사용하십시오.