खैर इतने अच्छे उत्तर, मैं इस पर और अधिक जोड़ना चाहता हूं। इससे समझने में मदद मिलेगी Extending v/s Implementing Thread
।
दो क्लास की फाइलों को बहुत बारीकी से बांधता है और कोड से निपटने के लिए कुछ बहुत मुश्किल पैदा कर सकता है।
दोनों दृष्टिकोण समान काम करते हैं लेकिन कुछ मतभेद रहे हैं।
सबसे आम अंतर है
- जब आप थ्रेड क्लास का विस्तार करते हैं, उसके बाद आप किसी अन्य वर्ग का विस्तार नहीं कर सकते हैं जिसकी आपको आवश्यकता है। (जैसा कि आप जानते हैं, जावा एक से अधिक वर्ग को इनहेरिट करने की अनुमति नहीं देता है)।
- जब आप रननेबल को लागू करते हैं, तो आप भविष्य में या अब किसी भी अन्य वर्ग का विस्तार करने के लिए अपनी कक्षा के लिए स्थान बचा सकते हैं।
हालाँकि, Runnable को लागू करने और थ्रेड को विस्तारित करने के बीच एक महत्वपूर्ण अंतर यह है कि
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
निम्नलिखित उदाहरण आपको अधिक स्पष्ट रूप से समझने में मदद करेगा
//Implement Runnable Interface...
class ImplementsRunnable implements Runnable {
private int counter = 0;
public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}
//Extend Thread class...
class ExtendsThread extends Thread {
private int counter = 0;
public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
}
//Use the above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {
public static void main(String args[]) throws Exception {
// Multiple threads share the same object.
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t3 = new Thread(rc);
t3.start();
// Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
उपरोक्त कार्यक्रम का आउटपुट।
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
रननेबल इंटरफ़ेस दृष्टिकोण में, एक वर्ग का केवल एक उदाहरण बनाया जा रहा है और इसे विभिन्न थ्रेड्स द्वारा साझा किया गया है। इसलिए प्रत्येक और हर थ्रेड पहुंच के लिए काउंटर का मूल्य बढ़ाया जाता है।
जबकि, थ्रेड क्लास दृष्टिकोण, आपको प्रत्येक थ्रेड एक्सेस के लिए अलग इंस्टेंस बनाना होगा। इसलिए हर वर्ग के उदाहरणों के लिए अलग-अलग मेमोरी आवंटित की जाती है और प्रत्येक में अलग-अलग काउंटर होते हैं, मूल्य समान रहता है, जिसका अर्थ है कि कोई वेतन वृद्धि नहीं होगी क्योंकि ऑब्जेक्ट संदर्भ में से कोई भी समान नहीं है।
Runnable का उपयोग कब करें?
जब आप थ्रेड के समूह से समान संसाधनों का उपयोग करना चाहते हैं, तो Runnable इंटरफ़ेस का उपयोग करें। यहां थ्रेड क्लास का उपयोग करने से बचें, क्योंकि कई वस्तुओं का निर्माण अधिक मेमोरी का उपभोग करता है और यह एक बड़ा प्रदर्शन ओवरहेड बन जाता है।
एक वर्ग जो रननेबल को लागू करता है वह एक धागा नहीं है और सिर्फ एक वर्ग है। एक रनवेबल थ्रेड बनने के लिए, आपको थ्रेड की एक आवृत्ति बनाने और खुद को लक्ष्य के रूप में पारित करने की आवश्यकता है।
अधिकांश मामलों में, Runnable इंटरफ़ेस का उपयोग किया जाना चाहिए यदि आप केवल run()
विधि को ओवरराइड करने की योजना बना रहे हैं और कोई अन्य थ्रेड विधियाँ नहीं हैं। यह महत्वपूर्ण है क्योंकि वर्गों को तब तक उप-वर्गित नहीं किया जाना चाहिए जब तक कि प्रोग्रामर वर्ग के मौलिक व्यवहार को संशोधित करने या बढ़ाने पर निर्भर न हो।
जब एक सुपरक्लास का विस्तार करने की आवश्यकता होती है, तो थ्रेड क्लास का उपयोग करने की तुलना में रननेबल इंटरफ़ेस को लागू करना अधिक उपयुक्त होता है। क्योंकि हम एक धागा बनाने के लिए रननेबल इंटरफ़ेस को लागू करते समय एक और वर्ग का विस्तार कर सकते हैं।
मुझे उम्मीद है कि इससे सहायता मिलेगी!