6

थ्रेड क्लास को विस्तारित करके उपयोगकर्ता को थ्रेड बनाने की अनुमति देने का सार क्या है जब हम रननेबल को लागू करके समान थ्रेड कन्स्ट्रक्टर को पास कर सकते हैं।java.lang क्यों है। जावा में थ्रेड क्लास डिजाइनरों द्वारा अंतिम रूप से चिह्नित नहीं है?

उत्तर

2

Thread असामान्य है कि यह Runnable को चलाने के लिए संदर्भ ले सकता है, लेकिन यह स्वयं भी Runnable है। डिफ़ॉल्ट रूप से, Thread खुद को Runnable उदाहरण के रूप में उपयोग करने के लिए उपयोग करेगा, बेशक आप इसे कहीं और इंगित कर सकते हैं।

मुझे लगता है कि है कि या तो निशान Thread अंतिम करने के लिए कोई अच्छा कारण नहीं है और Thread लचीला बनाने के लिए एक बाहरी Runnable या आवश्यकता होती है और यह अपने आप ही Runnable होना है। दोनों दृष्टिकोण पूरी तरह से ठीक हैं और न ही दूसरे की तुलना में एक बेहतर विकल्प की तरह लगता है।

Thread t = new Thread() { 
    public void run() { 
     /* ... your code here ... */ 
    } 
}; 

कौन सा Runnable का एक उपवर्ग बनाने और फिर एक में यह लपेटकर से मामूली रूप से क्लीनर है:

तो मुझे लगता है कि करने के लिए किया था, Thread subclassable बनाने के लिए कारण यह है कि यह आप इस तरह कोड लिखने की अनुमति देता है धागा। इसी प्रकार, Runnable प्राप्त करने के लिए आप Thread से उप-वर्ग को घटा सकते हैं जो स्पष्ट रूप से इंगित करता है कि इसे थ्रेड के रूप में उपयोग किया जाना चाहिए। बेशक, यह ज्यादातर सौंदर्यशास्त्र का सवाल है, और जावा डिजाइनर इस तरह से दूसरे तरीके से चले गए थे, मुझे लगता है कि यह एक बिल्कुल अच्छा निर्णय होगा।

+0

यह वाक्यविन्यास की भावना में क्लीनर है, लेकिन डिज़ाइन की भावना में क्लीनर नहीं है और वर्तमान क्लास लोडर को अनलोड किए जाने पर क्रूर प्रभाव (परम जीन रिसाव) हो सकता है (उदा। ऐप सर्वर में)। –

+0

@ पियोटर, कक्षा कचरा और सभी स्थैतिक जाज, दुर्भाग्यवश, थ्रेड को ओवरराइड करके हल नहीं किया जाएगा, सीसीएल को मृत धागे पर भी संदर्भ के रूप में रखा जाता है, जो अकेले पर्याप्त नुकसान पहुंचा सकता है। विरासत में पहुँचने के लिए कंट्रोल और रननेबल चलने वाले थ्रेड पर रखा जाता है, इसलिए बड़ा अंतर इमो। – bestsss

+0

धागे को ओवरराइड करने से कुछ प्रभाव पड़ते हैं, जैसे खतरनाक धागे उप-वर्गों पर ट्रैक रखना (जैसे ओवरराइड/setContextClassLoader()) जिसके परिणामस्वरूप कुछ अतिरिक्त संचालन और सिंक्रनाइज़ेशन होते हैं। 'Thread.isCCLOverridden (कक्षा)' – bestsss

0

एक ध्यान देने योग्य अंतर यह है कि यदि आपकी कक्षा ए को कक्षा बी (अन्य थ्रेड) का विस्तार करने की आवश्यकता है और एक ही समय में एक धागा हो, तो इसे रननेबल को लागू करना होगा।

3

विस्तार थ्रेड के उपयोग Runnable तक सीमित नहीं है Runnable को लागू करने द्वारा ही कार्यक्षमता को प्राप्त करने और धागा निर्माता यह लिए गुजरती हैं। उदाहरण के लिए आप change the behavior of some methods कर सकते हैं या अपनी खुद की थ्रेड स्थानीय जानकारी जोड़ सकते हैं (हमेशा Thread.currentThread() के साथ सुलभ)।

+0

+1 ग्रेट विचार .. – Daniel

0

मैं कुछ जोड़ने, विस्तार Thread आप एक धागा की कार्यक्षमता (जो Runnable में मौजूद नहीं है, क्योंकि यह केवल run() विधि शामिल हैं) अपने धागा एक डेमॉन धागा के रूप में कार्य करने के लिए अनुमति की तरह विस्तार किया है सकते हैं द्वारा ACAN हैं (बस कचरा कलेक्टर डेमॉन थ्रेड की तरह)। अन्य थ्रेड एक गैर-डिमन थ्रेड की तरह मौजूद हैं जो मुख्य कक्षा के तरीके (जब JVM प्रारंभ होता है) को कॉल करता है।

Runnable इंटरफ़ेस आपकी कक्षा को थ्रेड के रूप में सक्रिय होने की अनुमति देता है (run() विधि लागू करके)।

3

एक ऐतिहासिक परिप्रेक्ष्य से, आपको यह समझने की आवश्यकता है कि Thread एपीआई जावा 1.0 में डिज़ाइन किया गया था, जावा अज्ञात आंतरिक कक्षाओं का समर्थन करने से पहले। और प्रारंभिक उदाहरण कोड में से बहुत से Thread के उप-वर्गीकरण को दिखाता है। यह तब तक नहीं था जब तक:

  • उन्होंने अज्ञात आंतरिक कक्षाओं (जावा 1) के लिए समर्थन जोड़ा।1)
  • वे पता लगा यह इनर क्लासों (आदि) का उपयोग करने के Runnable उदाहरणों
  • वे कार्य निष्पादन, धागा पूल और इतने पर के लिए मानक वर्गों कार्यान्वित (जावा 5.0) प्रदान करने के लिए बेहतर था।

यह सब बहुत अच्छी तरह से कहा, "नेट में थ्रेड वर्ग अंतिम चिह्नित है", लेकिन आप को एहसास है कि सी # है/नेट बाद के वर्षों के एक नंबर साथ आया था ... और करने में सक्षम था जावा के डिजाइन से सीखें। जावा पुराने कोड को तोड़ने के लिए अनिवार्य अनिवार्य होने की वजह से कई कम से कम सही डिजाइन निर्णयों के ऐतिहासिक सामान के साथ अटक गया था।

0

थ्रेड क्लास वर्णन करता है कि थ्रेड कैसे चलता है, रननेबल बताता है कि क्या चल रहा है। यदि आप जो भी चलाना चाहते हैं उसे संशोधित करना चाहते हैं, तो आपको रननेबल को लागू करना चाहिए। यदि आप संशोधित करना चाहते हैं कि थ्रेड कैसे चलाया जाता है तो आप थ्रेड से प्राप्त होते हैं। उस स्थिति में जहां आप संशोधित करना चाहते हैं कि थ्रेड कैसे चलाया जाता है, आप थ्रेड से प्राप्त कर सकते हैं और एक अलग रननेबल ऑब्जेक्ट को कार्यान्वित कर सकते हैं।

0

एकमात्र अच्छी चीज जो मैं सोच सकता हूं वह है: यदि आप थ्रेड क्लास का विस्तार करते हैं, तो यह आपके रन() विधि को संरक्षित के रूप में चिह्नित करने देता है। एक रननेबल को लागू करने का नुकसान यह है कि आपकी रन विधि को सार्वजनिक के रूप में चिह्नित किया जाना चाहिए।

संबंधित मुद्दे