[c#] ThreadStatic 대 ThreadLocal <T> : 일반이 속성보다 낫습니까?

[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을 사용하십시오.


답변