java "लागू रननेबल" बनाम "थ्रेड फैलाता है"




multithreading runnable (24)

चूंकि यह एक बहुत ही लोकप्रिय विषय है और अच्छे उत्तरों को पूरी तरह से फैलाया गया है और बड़ी गहराई से निपटाया गया है, मुझे लगा कि दूसरों के अच्छे उत्तरों को अधिक संक्षिप्त रूप में संकलित करना उचित है, इसलिए नए आने वालों के पास एक आसान अवलोकन है:

  1. आप आमतौर पर कार्यक्षमता जोड़ने या संशोधित करने के लिए कक्षा का विस्तार करते हैं। इसलिए, यदि आप किसी भी थ्रेड व्यवहार को ओवरराइट नहीं करना चाहते हैं , तो रननेबल का उपयोग करें।

  2. उसी रोशनी में, यदि आपको थ्रेड विधियों का उत्तराधिकारी करने की आवश्यकता नहीं है , तो आप रननेबल का उपयोग कर उस ओवरहेड के बिना कर सकते हैं।

  3. एकल विरासत : यदि आप थ्रेड का विस्तार करते हैं तो आप किसी भी अन्य वर्ग से विस्तार नहीं कर सकते हैं, इसलिए यदि आपको ऐसा करने की ज़रूरत है, तो आपको रननेबल का उपयोग करना होगा।

  4. तकनीकी तर्कों से डोमेन तर्क को अलग करने के लिए यह एक अच्छा डिज़ाइन है, इस अर्थ में आपके धावक से अपने कार्य को अलग करने के लिए एक रननेबल कार्य होना बेहतर है।

  5. आप एक ही रननेबल ऑब्जेक्ट को कई बार निष्पादित कर सकते हैं, थ्रेड ऑब्जेक्ट, हालांकि, केवल एक बार शुरू किया जा सकता है। (शायद कारण, क्यों निष्पादक Runnables स्वीकार करते हैं, लेकिन धागे नहीं।)

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

  7. यह आपके यूनिट परीक्षणों में कार्य-तर्क और समवर्ती पहलुओं को अलग करना भी आसान बनाता है।

  8. यदि आप इस प्रश्न में रुचि रखते हैं, तो आप कॉलबल और रननेबल के बीच के अंतर में रुचि भी ले सकते हैं।

जावा में धागे के साथ मैंने किस समय बिताया है, मैंने धागे लिखने के इन दो तरीकों को पाया है:

उपकरण के साथ implements Runnable :

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

या, extends Thread साथ:

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

कोड के इन दो ब्लॉक में कोई महत्वपूर्ण अंतर है?


चलने योग्य क्योंकि:

  • एक और वर्ग का विस्तार करने के लिए रननेबल कार्यान्वयन के लिए अधिक लचीलापन छोड़ देता है
  • कोड निष्पादन से अलग करता है
  • आपको थ्रेड पूल, इवेंट थ्रेड, या भविष्य में किसी भी अन्य तरीके से अपना रननेबल चलाने की अनुमति देता है।

भले ही आपको इनमें से किसी की आवश्यकता नहीं है, फिर भी आप भविष्य में हो सकते हैं। चूंकि थ्रेड को ओवरराइड करने का कोई फायदा नहीं है, इसलिए रननेबल एक बेहतर समाधान है।


मैं एक विशेषज्ञ नहीं हूं, लेकिन मैं थ्रेड का विस्तार करने के बजाए रननेबल को लागू करने के एक कारण के बारे में सोच सकता हूं: जावा केवल एकल विरासत का समर्थन करता है, ताकि आप केवल एक वर्ग का विस्तार कर सकें।

संपादित करें: यह मूल रूप से कहा गया है "एक इंटरफ़ेस को कार्यान्वित करने के लिए कम संसाधनों की आवश्यकता होती है।" साथ ही, लेकिन आपको किसी भी नए थ्रेड इंस्टेंस को किसी भी तरह से बनाने की आवश्यकता है, इसलिए यह गलत था।


एक बात जो मैं आश्चर्यचकित हूं, अभी तक उल्लेख नहीं किया गया है कि Runnable लागू करने से आपकी कक्षा अधिक लचीला हो जाती है।

यदि आप धागे का विस्तार करते हैं तो आप जो क्रिया कर रहे हैं वह हमेशा थ्रेड में होगी। हालांकि, अगर आप Runnable लागू करते हैं तो यह होना आवश्यक नहीं है। आप इसे थ्रेड में चला सकते हैं, या इसे किसी प्रकार की एक्जिक्यूटर सेवा में पास कर सकते हैं, या बस इसे एक थ्रेडेड एप्लिकेशन के भीतर एक कार्य के रूप में पास कर सकते हैं (शायद बाद में चलने के लिए, लेकिन उसी थ्रेड में)। यदि आप Thread खुद को बांधते हैं तो विकल्प केवल Runnable उपयोग करते हैं, तो विकल्प बहुत अधिक खुले होते हैं।


I find it is most useful to use Runnable for all the reasons mentioned, but sometimes I like to extend Thread so I can create my own thread stopping method and call it directly on the thread I have created.


This is discussed in Oracle's Defining and Starting a Thread tutorial:

Which of these idioms should you use? The first idiom, which employs a Runnable object, is more general, because the Runnable object can subclass a class other than Thread. The second idiom is easier to use in simple applications, but is limited by the fact that your task class must be a descendant of Thread. This lesson focuses on the first approach, which separates the Runnable task from the Thread object that executes the task. Not only is this approach more flexible, but it is applicable to the high-level thread management APIs covered later.

In other words, implementing Runnable will work in scenarios where your class extends a class other than Thread . Java does not support multiple inheritance. Also, extending Thread will not be possible when using some of the high-level thread management APIs. The only scenario where extending Thread is preferable is in a small application that won't be subject to updates in future. It is almost always better to implement Runnable as it is more flexible as your project grows. A design change won't have a major impact as you can implement many interfaces in java, but only extend one class.


हां: कार्यान्वयन Runnable इसे करने का पसंदीदा तरीका है, आईएमओ। आप वास्तव में धागे के व्यवहार का विशेषज्ञ नहीं हैं। आप इसे चलाने के लिए कुछ दे रहे हैं। इसका मतलब है कि composition दार्शनिक रूप से "शुद्ध" रास्ता है।

व्यावहारिक शब्दों में, इसका मतलब है कि आप Runnable को लागू कर सकते हैं और एक और कक्षा से भी विस्तार कर सकते हैं।


बहुत अच्छे जवाब, मैं इस पर और अधिक जोड़ना चाहता हूं। इससे Extending v/s Implementing Thread को समझने में मदद मिलेगी।
दो वर्ग फ़ाइलों को बहुत बारीकी से बढ़ाता है और कोड से निपटने के लिए कुछ कठिन हो सकता है।

दोनों दृष्टिकोण एक ही काम करते हैं लेकिन कुछ मतभेद हैं।
सबसे आम अंतर है

  1. जब आप थ्रेड क्लास को बढ़ाते हैं, उसके बाद आप किसी अन्य श्रेणी को विस्तारित नहीं कर सकते हैं। (जैसा कि आप जानते हैं, जावा एक से अधिक कक्षा में विरासत की अनुमति नहीं देता है)।
  2. जब आप रननेबल लागू करते हैं, तो आप भविष्य में या अब किसी भी अन्य वर्ग को विस्तारित करने के लिए अपनी कक्षा के लिए एक स्थान सहेज सकते हैं।

हालांकि, चलने योग्य और विस्तारित थ्रेड को लागू करने के बीच एक महत्वपूर्ण अंतर यह है
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 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

रननेबल इंटरफ़ेस दृष्टिकोण में, कक्षा का केवल एक उदाहरण बनाया जा रहा है और इसे विभिन्न धागे द्वारा साझा किया गया है। इसलिए काउंटर का मूल्य प्रत्येक थ्रेड एक्सेस के लिए बढ़ाया जाता है।

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

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

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

ज्यादातर मामलों में, रननेबल इंटरफ़ेस का उपयोग किया जाना चाहिए यदि आप केवल run() विधि को ओवरराइड करने और अन्य थ्रेड विधियों को ओवरराइड करने की योजना बना रहे हैं। यह महत्वपूर्ण है क्योंकि कक्षाओं को उप-वर्गीकृत नहीं किया जाना चाहिए जब तक कि प्रोग्रामर कक्षा के मौलिक व्यवहार को संशोधित या बढ़ाने पर इरादा नहीं रखता।

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

मुझे उम्मीद है कि इससे सहायता मिलेगी!


If I am not wrong, it's more or less similar to

इंटरफेस और अमूर्त वर्ग के बीच क्या अंतर है?

extends establishes " Is A " relation & interface provides " Has a " capability.

Prefer implements Runnable :

  1. If you don't have to extend Thread class and modify Thread API default implementation
  2. If you are executing a fire and forget command
  3. If You are already extending another class

Prefer " extends Thread " :

  1. If you have to override any of these Thread methods as listed in oracle documentation page

Generally you don't need to override Thread behaviour. So implements Runnable is preferred for most of the times.

On a different note, using advanced ExecutorService or ThreadPoolExecutorService API provides more flexibility and control.

Have a look at this SE Question:

ExecutorService vs Casual Thread Spawner


Difference between Thread and runnable .If we are creating Thread using Thread class then Number of thread equal to number of object we created . If we are creating thread by implementing the runnable interface then we can use single object for creating multiple thread.So single object is shared by multiple Thread.So it will take less memory

So depending upon the requirement if our data is not senstive. So It can be shared between multiple Thread we can used Runnable interface.


Adding my two cents here - Always whenever possible use implements Runnable . Below are two caveats on why you should not use extends Thread s

  1. Ideally you should never extend the Thread class; the Thread class should be made final . At least its methods like thread.getId() . See this discussion for a bug related to extending Thread s.

  2. Those who like to solve puzzles can see another side effect of extending Thread. The below code will print unreachable code when nobody is notifying them.

Please see http://pastebin.com/BjKNNs2G .

public class WaitPuzzle {

    public static void main(String[] args) throws InterruptedException {
        DoNothing doNothing = new DoNothing();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        Thread.sleep(100);
        doNothing.start();
        while(true) {
            Thread.sleep(10);
        }
    }


    static class WaitForever extends  Thread {

        private DoNothing doNothing;

        public WaitForever(DoNothing doNothing) {
            this.doNothing =  doNothing;
        }

        @Override
        public void run() {
            synchronized (doNothing) {
                try {
                    doNothing.wait(); // will wait forever here as nobody notifies here
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Unreachable Code");
            }
        }
    }

    static class DoNothing extends Thread {

        @Override
        public void run() {
            System.out.println("Do Nothing ");
        }
    } 
}

Separating the Thread class from the Runnable implementation also avoids potential synchronization problems between the thread and the run() method. A separate Runnable generally gives greater flexibility in the way that runnable code is referenced and executed.


जावा 8 के रिलीज के साथ, अब एक तीसरा विकल्प है।

Runnable एक कार्यात्मक इंटरफ़ेस है , जिसका अर्थ है कि इसका उदाहरण लैम्ब्डा अभिव्यक्तियों या विधि संदर्भों के साथ बनाया जा सकता है।

आपका उदाहरण इसके साथ प्रतिस्थापित किया जा सकता है:

new Thread(() -> { /* Code here */ }).start()

या यदि आप किसी ExecutorService और विधि संदर्भ का उपयोग करना चाहते हैं:

executor.execute(runner::run)

ये आपके उदाहरणों से बहुत कम नहीं हैं, बल्कि Thread पर Runnable का उपयोग करने के अन्य उत्तरों में बताए गए कई फायदों के साथ भी आते हैं, जैसे एकल जिम्मेदारी और रचना का उपयोग करना क्योंकि आप धागे के व्यवहार को विशेषज्ञता नहीं दे रहे हैं। इस तरह यदि आप की जरूरत है तो एक अतिरिक्त वर्ग बनाने से बचाता है जैसा कि आप अपने उदाहरणों में करते हैं।


कहानी का नैतिक:

केवल तभी प्रवेश करें जब आप कुछ व्यवहार को ओवरराइड करना चाहते हैं।

या इसके बजाय इसे पढ़ना चाहिए:

कम विरासत, इंटरफेस और अधिक।


Yes, If you call ThreadA call , then not need to call the start method and run method is call after call the ThreadA class only. But If use the ThreadB call then need to necessary the start thread for call run method. If you have any more help, reply me.


if you use runnable you can save the space to extend to any of your other class.


आपको रननेबल को लागू करना चाहिए, लेकिन यदि आप जावा 5 या उच्चतर पर चल रहे हैं, तो आपको इसे new Thread शुरू नहीं करना चाहिए बल्कि इसके बजाय ExecutorService उपयोग करना चाहिए। विवरण के लिए देखें: जावा में सरल थ्रेडिंग को कैसे कार्यान्वित करें


Java does not support multiple inheritence so if you extends Thread class then no other class will be extended.

For Example: If you create an applet then it must extends Applet class so here the only way to create thread is by implementing Runnable interface


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


मैं कहूंगा कि तीसरा तरीका है:

public class Something {

    public void justAnotherMethod() { ... }

}

new Thread(new Runnable() {
   public void run() {
    instanceOfSomething.justAnotherMethod();
   }
}).start();

हो सकता है कि यह जावास्क्रिप्ट और एक्शनस्क्रिप्ट 3 के अपने हालिया भारी उपयोग से थोड़ा प्रभावित हो, लेकिन इस तरह आपकी कक्षा को Runnable जैसे सुंदर अस्पष्ट इंटरफ़ेस को लागू करने की आवश्यकता नहीं है।


One reason you'd want to implement an interface rather than extend a base class is that you are already extending some other class. You can only extend one class, but you can implement any number of interfaces.

If you extend Thread, you're basically preventing your logic to be executed by any other thread than 'this'. If you only want some thread to execute your logic, it's better to just implement Runnable.


यहां हर कोई ऐसा लगता है कि रननेबल को लागू करने का तरीका है और मैं वास्तव में उनके साथ असहमत नहीं हूं लेकिन मेरी राय में थ्रेड बढ़ाने का भी एक मामला है, वास्तव में आपने इसे अपने कोड में प्रदर्शित किया है।

यदि आप रननेबल को लागू करते हैं तो रननेबल लागू करने वाली कक्षा का थ्रेड नाम पर कोई नियंत्रण नहीं होता है, यह कॉलिंग कोड है जो थ्रेड नाम सेट कर सकता है, जैसे:

new Thread(myRunnable,"WhateverNameiFeelLike");

लेकिन यदि आप थ्रेड का विस्तार करते हैं तो आपको इसे कक्षा के भीतर ही प्रबंधित करना होगा (जैसे कि आपके उदाहरण में आप थ्रेड 'थ्रेडबी' नाम दें)। इस मामले में आप:

ए) इसे डीबगिंग उद्देश्यों के लिए एक और उपयोगी नाम दे सकता है

बी) इस वर्ग के सभी उदाहरणों के लिए उस नाम का उपयोग किया जा रहा है (जब तक कि आप इस तथ्य को अनदेखा न करें कि यह एक धागा है और इसके साथ उपर्युक्त है जैसे कि यह एक रननेबल है लेकिन हम किसी भी मामले में यहां सम्मेलन के बारे में बात कर रहे हैं उस संभावना को अनदेखा करें जो मुझे लगता है)।

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

यह एक छोटी सी चीज की तरह प्रतीत हो सकता है, लेकिन जहां आपके पास बहुत सारे धागे के साथ बहुत ही जटिल अनुप्रयोग है और अचानक चीजें 'बंद हो गई हैं' (या तो डेडलॉक के कारणों के लिए या संभवतः नेटवर्क प्रोटोकॉल में दोष की वजह से जो कम होगा स्पष्ट - या अन्य अंतहीन कारण) फिर जावा से एक स्टैक डंप प्राप्त करना जहां सभी धागे को 'थ्रेड -1', 'थ्रेड -2', 'थ्रेड -2' कहा जाता है, हमेशा थ्रेड-3 नहीं होता है (यह इस बात पर निर्भर करता है कि आपके धागे कैसे हैं संरचित और क्या आप उपयोगी रूप से बता सकते हैं कि केवल उनके स्टैक ट्रेस द्वारा कौन सा है - यदि आप एक ही कोड को चलाने वाले एकाधिक धागे के समूह का उपयोग कर रहे हैं तो हमेशा संभव नहीं है)।

यह कहकर कि आप निश्चित रूप से थ्रेड क्लास का विस्तार बनाकर उपरोक्त तरीके से भी कर सकते हैं जो इसके नाम को अपने निर्माण कॉल के स्टैक ट्रेस पर सेट करता है और उसके बाद मानक जावा थ्रेड क्लास के बजाय अपने रननेबल कार्यान्वयन के साथ इसका उपयोग करता है (नीचे देखें) लेकिन स्टैक ट्रेस के अलावा वहां अधिक संदर्भ विशिष्ट जानकारी हो सकती है जो डिबगिंग के थ्रेड नाम में उपयोगी होगी (कई कतारों या सॉकेट्स में से एक का संदर्भ जो उदाहरण के लिए प्रसंस्करण कर सकता है, उदाहरण के लिए आप किस मामले में पसंद कर सकते हैं विशेष रूप से उस मामले के लिए थ्रेड का विस्तार करें ताकि आप नाम में उपयोग के लिए कुछ जानकारी (जैसे प्रश्न में कतार / सॉकेट) में पास करने के लिए संकलक बल (या दूसरों को अपने पुस्तकालयों का उपयोग कर) को पास कर सकें)।

कॉलिंग स्टैक ट्रेस के साथ जेनेरिक थ्रेड का एक उदाहरण यहां दिया गया है:

public class DebuggableThread extends Thread {
    private static String getStackTrace(String name) {
        Throwable t= new Throwable("DebuggableThread-"+name);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(os);
        t.printStackTrace(ps);
        return os.toString();
    }

    public DebuggableThread(String name) {
        super(getStackTrace(name));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(new Thread());
        System.out.println(new DebuggableThread("MainTest"));
    }
}

और यहां दो नामों की तुलना में आउटपुट का एक नमूना है:

Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
    at DebuggableThread.getStackTrace(DebuggableThread.java:6)
    at DebuggableThread.<init>(DebuggableThread.java:14)
    at DebuggableThread.main(DebuggableThread.java:19)
,5,main]

That's the S of SOLID : Single responsibility.

A thread embodies the running context (as in execution context: stack frame, thread id, etc.) of the asynchronous execution of a piece of code. That piece of code ideally should be the same implementation, whether synchronous or asynchronous .

If you bundle them together in one implementation, you give the resulting object two unrelated causes of change:

  1. thread handling in your application (ie. querying and modifying the execution context)
  2. algorithm implemented by the piece of code (the runnable part)

If the language you use supports partial classes or multiple inheritance, then you can segregate each cause in its own super class, but it boils down to the same as composing the two objects, since their feature sets don't overlap. That's for the theory.

In practice, generally speaking, a programme does not need to carry more complexity than necessary. If you have one thread working on a specific task, without ever changing that task, there is probably no point in making the tasks separate classes, and your code remains simpler.

In the context of Java , since the facility is already there , it is probably easier to start directly with stand alone Runnable classes, and pass their instances to Thread (or Executor ) instances. Once used to that pattern, it is not harder to use (or even read) than the simple runnable thread case.


One difference between implementing Runnable and extending Thread is that 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.

A class that implements Runnable is not a thread and just a class. For a Runnable to be executed by a Thread, you need to create an instance of Thread and pass the Runnable instance in as the target.

In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

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







java-threads