थ्रेडस्टैटिक बनाम थ्रेडलोकल <टी>: जेनेरिक विशेषता से बेहतर है?


95

[ThreadStatic]ThreadLocal<T>जेनेरिक का उपयोग करते समय विशेषता का उपयोग कर परिभाषित किया गया है । अलग-अलग डिज़ाइन समाधान क्यों चुना गया? इस मामले में जेनेरिक विशेषताओं का उपयोग करने के क्या फायदे और नुकसान हैं?


4
देखें reedcopsey.com/2009/11/12/… - मैं यह नहीं देखता कि इसका प्रतिबिंब के साथ क्या करना है ...
जॉन स्कीट

जवाबों:


112

टिप्पणियों में नोट किया गया कुछ ब्लॉग पोस्ट स्पष्ट नहीं करता है, लेकिन मुझे बहुत महत्वपूर्ण लगता है, यह है कि [ThreadStatic]हर थ्रेड के लिए चीजों को स्वचालित रूप से प्रारंभ नहीं करता है। उदाहरण के लिए, मान लें कि आपके पास यह है:

[ThreadStatic]
private static int Foo = 42;

इसका उपयोग करने वाला पहला धागा Fooआरंभिक रूप से दिखाई देगा 42। लेकिन बाद के धागे नहीं होंगे। इनिलाइज़र केवल पहले थ्रेड के लिए काम करता है। तो आप अंत में यह जांचने के लिए कोड लिखना चाहते हैं कि क्या यह आरंभिक है।

ThreadLocal<T> उस समस्या को हल करता है जिससे आप आरंभीकरण फ़ंक्शन (रीड के ब्लॉग शो के रूप में) की आपूर्ति कर सकते हैं जो पहली बार आइटम के एक्सेस होने से पहले चलता है।

मेरी राय में, [ThreadStatic]इसके बजाय का उपयोग करने के लिए कोई फायदा नहीं है ThreadLocal<T>


20
शायद, सिवाय इसके कि ThreadLocal<T>नेट 4 और में उपलब्ध है, और विशेषता भी 3.5 और नीचे में उपलब्ध है। ThreadStatic
जीरो

2
और यदि आप मूल्य निर्धारित करने के लिए इनिशियलाइज़र का उपयोग नहीं कर रहे हैं, लेकिन इसके बजाय इनिशियलाइज़ेशन के बाद कुछ बाद के बिंदु पर सेट कर रहे हैं, तो [थ्रेडस्टैटिक] का उपयोग सिंथेटिक रूप से क्लीनर है।
विचार

9
और इसके अलावा ThreadLocal<T>लागू करने IDisposableऔर आमतौर पर आपको लागू IDisposableकरने के लिए मजबूर करता है, जो आपके कॉल करने वालों को आपको निपटाने के लिए मजबूर करता है और इसलिए भी लागू होता है IDisposable...
स्टीफन स्टाइनगगर

4
@StefanSteinegger: मैं पूल थ्रेड्स का उपयोग करके ThreadLocalया उसके ThreadStaticसाथ बहुत सावधान रहूंगा । वे मूल्य पूल धागे के पूरे जीवन के माध्यम से रहेंगे, न कि केवल उस कार्य के लिए जो आप इसे असाइन करते हैं। जो आपको कुछ स्पष्ट गैर-स्पष्ट तरीकों से परेशान कर सकता है। अधिक जानकारी के लिए stackoverflow.com/questions/561518/… और इसी तरह के प्रश्न देखें ।
जिम मिसल जूल

3
उदाहरण के क्षेत्र में भी घोषित नहीं किया जाना चाहिए static? देखें msdn.microsoft.com/en-us/library/...
entheh

39

थ्रेडस्टैटिक इनिशियलाइज़ केवल पहले थ्रेड पर, थ्रेडलोकल इनिशियलाइज़ प्रत्येक थ्रेड के लिए। नीचे सरल प्रदर्शन है:

    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();
    }

यहां छवि विवरण दर्ज करें


15

थ्रेडस्टैटिक के पीछे मुख्य विचार प्रत्येक थ्रेड के लिए चर की एक अलग प्रतिलिपि बनाए रखना है ।

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प्रत्येक धागे के लिए एक अलग कॉपी है , जिसमें मुख्य धागा भी शामिल है।

यहां छवि विवरण दर्ज करें

तो, एक थ्रेडस्टैटिक वैरिएबल को थ्रेड को छोड़कर अन्य थ्रेड्स पर इसके डिफ़ॉल्ट मान पर आरम्भ किया जाएगा, जिस पर इसे बनाया गया है।

यदि हम अपने तरीके से प्रत्येक थ्रेड पर वैरिएबल को इनिशियलाइज़ करना चाहते हैं, तो थ्रेडलोकल का उपयोग करें।


1
और पूरा लेख यहाँ पाया जा सकता है
डेनियल ड्यूक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.