जावा में Runnable और Callable इंटरफेस के बीच अंतर


492

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


2
अतिरिक्त चर्चा के लिए, इस पृष्ठ को पढ़ने के बाद, देखें कि क्या Runnable पर कॉल किया जाना चाहिए?
बरफू

जवाबों:


444

स्पष्टीकरण यहाँ देखें ।

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


269

Runnableऔर के अनुप्रयोगों में क्या अंतर हैं Callable। क्या अंतर केवल रिटर्न पैरामीटर में मौजूद है Callable?

असल में, हाँ। इस प्रश्न के उत्तर देखें । और के लिए javadocCallable

दोनों होने की क्या जरूरत है जो Callableसब कर सकता Runnableहै?

क्योंकि Runnableइंटरफ़ेस सब कुछ नहीं करता है जो Callableकरता है!

Runnableजावा 1.0 के बाद से आस-पास रहा है, लेकिन Callableइसका उपयोग केवल जावा 1.5 में किया गया था ... उपयोग-मामलों को संभालने के लिए जो Runnableसमर्थन नहीं करता है। सिद्धांत रूप में, जावा टीम Runnable.run()विधि के हस्ताक्षर को बदल सकती थी , लेकिन इससे प्री-1.5 कोड के साथ बाइनरी कॉम्पिटिबिलिटी टूट जाती, जब पुराने जावा कोड को नए जेवीएम में स्थानांतरित करने के लिए रीकोडिंग की आवश्यकता होती है। वह BIG NO-NO है। जावा पीछे की ओर संगत होने का प्रयास करता है ... और यह व्यवसाय कंप्यूटिंग के लिए जावा के सबसे बड़े विक्रय बिंदुओं में से एक है।

और, जाहिर है, ऐसे उपयोग-मामले हैं जहां किसी कार्य को परिणाम वापस करने या चेक किए गए अपवाद को फेंकने की आवश्यकता नहीं है। उन उपयोग-मामलों के लिए, विधि से डमी ( ) मान Runnableका उपयोग करने Callable<Void>और वापस करने की तुलना में उपयोग करना अधिक संक्षिप्त है ।nullcall()


9
मुझे आश्चर्य है कि आपको यह इतिहास कहां से मिला। यह बहुत उपयोगी है।
स्पाइडरमैन

4
@ छाप - मूल तथ्य पुरानी पाठ्यपुस्तकों में पाए जाते हैं। संक्षेप में जावा के पहले संस्करण की तरह।
स्टीफन सी

4
(@ छाप - इसके अलावा ... जावा 1.1 युग में जावा का उपयोग शुरू करने से।)
स्टीफन सी

1
@StephenC यदि मैं आपके उत्तर को सही ढंग से पढ़ता हूं, तो आप सुझाव दे रहे हैं कि Runnableपिछड़े संगतता कारणों के लिए (बड़े पैमाने पर) मौजूद है। लेकिन क्या ऐसी परिस्थितियाँ नहीं हैं जहाँ यह अनावश्यक या बहुत महंगा है (या आवश्यकता होती है) Callableइंटरफ़ेस (जैसे, में ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)) को लागू करने के लिए ? तो क्या भाषा में दोनों इंटरफेस बनाए रखने का कोई लाभ नहीं है, यहां तक ​​कि इतिहास ने वर्तमान परिणाम को मजबूर नहीं किया है?
अधिकतम

1
@ मोम - वैसे मैंने कहा था, और मैं अभी भी इससे सहमत हूं। हालाँकि, यह एक गौण कारण है। लेकिन फिर भी, मुझे संदेह है कि अगर संगतता बनाए रखने के लिए आवश्यक नहीं था, Runnable तो इसे संशोधित किया जाएगा । का "बॉयलरप्लेट" return null;एक कमजोर तर्क है। (कम से कम, यह मेरा फैसला होगा ... काल्पनिक संदर्भ में, जहां आप पीछे की संगतता को नजरअंदाज कर सकते हैं।)
स्टीफन सी।

81
  • एक Callableको लागू करने की जरूरत है call()विधि थोड़ी देर Runnableजरूरतों को लागू करने की run()विधि।
  • A Callableमान वापस कर सकता है, लेकिन Runnableनहीं कर सकता।
  • A Callableचेक अपवाद को फेंक सकता है लेकिन ऐसा Runnableनहीं कर सकता।
  • A Callableका उपयोग ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)विधियों के साथ किया जा सकता है लेकिन Runnableनहीं हो सकता।

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    

17
ExecutorService.submit (रन करने योग्य कार्य) भी मौजूद है और बहुत उपयोगी है
यार कुकिल्का

Runnable को ExecutorService के साथ निम्नलिखित तरीकों से भी इस्तेमाल किया जा सकता है- 1) ExecutorService.execute (Runnable) 2) ExecutorService.submit (Runnable)
आज़म खान

2
इसके अलावा Executor.submit (Callable <T> कार्य) है, लेकिन आप रन नहीं कर सकते हैं या Runnable कार्यों के संग्रह के साथ InvokeAny <? विस्तार योग्य <T >> कार्य
nikli

36

मैंने इसे एक अन्य ब्लॉग में पाया जो इन अंतरों को थोड़ा और समझा सकता है :

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

  • एक Callable<V>उदाहरण प्रकार का परिणाम देता है V, जबकि एक Runnableउदाहरण नहीं देता है।
  • एक Callable<V>उदाहरण जाँच अपवाद को फेंक सकता है, जबकि एक Runnableउदाहरण नहीं हो सकता

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


27

आइए हम देखें कि कोई व्यक्ति Runnable और Callable का उपयोग कहां करेगा।

रननेबल और कॉलेबल दोनों ही कॉलिंग थ्रेड से अलग थ्रेड पर चलते हैं। लेकिन Callable एक मान लौटा सकता है और Runnable नहीं कर सकता। तो यह वास्तव में कहां लागू होता है।

Runnable : यदि आपके पास आग है और कार्य भूल जाते हैं, तो Runnable का उपयोग करें। अपने कोड को रननेबल के अंदर रखें और जब रन () विधि कहा जाता है, तो आप अपना कार्य कर सकते हैं। कॉलिंग थ्रेड वास्तव में परवाह नहीं करता है जब आप अपना कार्य करते हैं।

कॉल करने योग्य : यदि आप किसी कार्य से मान प्राप्त करने का प्रयास कर रहे हैं, तो कॉल करने योग्य का उपयोग करें। अब कॉल करने योग्य अपने आप काम नहीं करेगा। आपको एक Future की आवश्यकता होगी जिसे आप अपने Callable के चारों ओर लपेटते हैं और Future.get () पर अपने मान प्राप्त करते हैं। यहां कॉलिंग थ्रेड को तब तक के लिए ब्लॉक कर दिया जाएगा जब तक कि फ्यूचर रिजल्ट के साथ वापस नहीं आ जाता है, जिसके परिणामस्वरूप कॉल करने योग्य कॉल () विधि को निष्पादित करने की प्रतीक्षा है।

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

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


14

Callableइंटरफ़ेस call()विधि की घोषणा करता है और आपको ऑब्जेक्ट कॉल के प्रकार के रूप में जेनरिक प्रदान करना चाहिए () वापस आना चाहिए -

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Runnableदूसरी ओर वह इंटरफ़ेस है जो run()विधि की घोषणा करता है जिसे कहा जाता है जब आप रन करने योग्य और कॉल प्रारंभ () के साथ एक थ्रेड बनाते हैं। आप सीधे रन रन () भी कह सकते हैं, लेकिन बस रन को निष्पादित करें () विधि समान थ्रेड है।

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

संक्षेप में कुछ उल्लेखनीय अंतर हैं

  1. एक Runnable, जबकि एक वस्तु एक परिणाम वापस नहीं करता Callableवस्तु एक परिणाम देता है।
  2. एक Runnableवस्तु एक अपवाद को नहीं छोड़ Callableसकती है।
  3. Runnableइंटरफ़ेस जावा 1.0 के बाद से आसपास किया गया है, जबकि Callableकेवल जावा 1.5 में पेश किया गया था।

कुछ समानताओं में शामिल हैं

  1. रननेबल या कॉल करने योग्य इंटरफेस को लागू करने वाले वर्गों के उदाहरणों को संभावित रूप से किसी अन्य थ्रेड द्वारा निष्पादित किया जाता है।
  2. Callable और Runnable दोनों इंटरफेस के उदाहरण ExecutorService द्वारा सबमिट () विधि के माध्यम से निष्पादित किए जा सकते हैं।
  3. दोनों कार्यात्मक इंटरफेस हैं और Java8 के बाद से लैंबडा एक्सप्रेशन में इस्तेमाल किए जा सकते हैं।

ExecutorService इंटरफ़ेस में विधियाँ हैं

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);

13

ओरेकल प्रलेखन से इन इंटरफेस का उद्देश्य:

रनने योग्य इंटरफ़ेस को किसी भी वर्ग द्वारा लागू किया जाना चाहिए जिनके उदाहरणों को ए द्वारा निष्पादित किया जाना है Thread। वर्ग को बिना किसी तर्क के एक विधि को परिभाषित करना चाहिए run

कॉल करने योग्य : एक कार्य जो एक परिणाम देता है और एक अपवाद फेंक सकता है। कार्यान्वयनकर्ता एकल पद्धति को परिभाषित करता है जिसका कोई तर्क नहीं है जिसे कॉल कहा जाता है। Callableइंटरफ़ेस के समान है Runnableमें है कि दोनों वर्गों जिसका उदाहरणों संभवतः एक और धागा द्वारा क्रियान्वित कर रहे के लिए तैयार कर रहे हैं,। ए Runnable, हालांकि, एक परिणाम नहीं लौटाता है और एक जाँच अपवाद को फेंक नहीं सकता है।

अन्य अंतर:

  1. आप Runnableएक थ्रेड बनाने के लिए पास कर सकते हैं । लेकिन आप Callableपैरामीटर के रूप में पास करके नया थ्रेड नहीं बना सकते । आप केवल ExecutorServiceउदाहरण के लिए Callable पास कर सकते हैं ।

    उदाहरण:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
  2. Runnableआग और भूल कॉल का उपयोग करें । Callableपरिणाम को सत्यापित करने के लिए उपयोग करें ।

  3. Callableविपरीत invokeAll विधि के लिए पारित किया जा सकता है Runnable। तरीके invokeAnyऔर invokeAllथोक निष्पादन के सबसे उपयोगी रूपों को निष्पादित करते हैं, कार्यों के संग्रह को निष्पादित करते हैं और फिर कम से कम एक, या सभी को पूरा करने की प्रतीक्षा करते हैं

  4. तुच्छ अंतर: विधि का नाम लागू करने के लिए => के run()लिए Runnableऔर के call()लिए Callable


11

जैसा कि यह पहले ही उल्लेख किया गया था कि कॉलेबल अपेक्षाकृत नया इंटरफ़ेस है और इसे कॉनक्योरिटी पैकेज के एक भाग के रूप में पेश किया गया था। निष्पादन योग्य के साथ Callable और Runnable दोनों का उपयोग किया जा सकता है। क्लास थ्रेड (जो कि रननेबल को लागू करता है) केवल रननेबल का समर्थन करता है।

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


मुझे आश्चर्य है कि जावा में एक थ्रेडिंग अपवाद पर उदाहरण क्या है? क्या मुख्य धागा उस अपवाद को पकड़ने में सक्षम होगा? यदि नहीं, तो मैं Callable का उपयोग नहीं करेगा। एलेक्स, क्या आपके पास इस पर कुछ अंतर्दृष्टि है? धन्यवाद!
खरब

1
कस्टम थ्रेड में चल रहे कोड के रूप में किसी भी अन्य कोड अपवाद फेंक सकते हैं। इसे दूसरे धागे में पकड़ने के लिए आपको या तो कस्टम नोटिफिकेशन मेकेनिज्म (जैसे श्रोताओं पर आधारित) का उपयोग करके Futureया हुक लगाकर या बिना किसी अपवाद के सभी कैच को जोड़कर कुछ प्रयास करने होंगे: docs.oracle.com/javase/6/docs/apn/ java / lang /…
9

बढ़िया जानकारी! धन्यवाद, एलेक्स! :)
खरब

1
मैंने इस उत्तर को उकेरा क्योंकि यह (अंकित मूल्य पर सही ढंग से लिया गया) दावा करता है कि किसी को कॉल करने योग्य वस्तुओं के साथ थ्रेड पूल मॉडल का उपयोग करना चाहिए। इसके बारे में स्पष्ट रूप से दुर्भाग्यपूर्ण बात यह है कि कोई इंटरफ़ेस Threadका सार्थक उपयोग करने के लिए विस्तार नहीं कर सकता Callableहै ताकि एक एकल थ्रेड को कॉल करने योग्य चीजों और अन्य चीजों को करने के लिए अनुकूलित किया जा सके जो डेवलपर को चाहिए। अगर कोई भी इस टिप्पणी को पढ़ता है, तो मुझे लगता है कि मैं गलत हूं, मैं बेहतर जानना चाहता हूं ...

8
+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              Runnable               |                                           Callable<T>                                            |
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library                                           |
| Runnable cannot be parametrized     | Callable is a parametrized type whose type parameter indicates the return type of its run method |
| Runnable has run() method           | Callable has call() method                                                                       |
| Runnable.run() returns void         | Callable.call() returns a value of Type T                                                        |
| Can not throw Checked Exceptions    | Can throw Checked Exceptions                                                                     |
+-------------------------------------+--------------------------------------------------------------------------------------------------+

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


7

Callable और Runnable के बीच अंतर निम्नलिखित हैं:

  1. Callable को JDK 5.0 में पेश किया गया है लेकिन Runnable को JDK 1.0 में पेश किया गया है
  2. Callable में कॉल () विधि है लेकिन Runnable ने रन () विधि की है।
  3. Callable में कॉल विधि है जो मान लौटाती है लेकिन Runnable में रन विधि है जो किसी भी मान को वापस नहीं करती है।
  4. कॉल विधि जाँच अपवाद को फेंक सकती है लेकिन रन विधि जाँच अपवाद को फेंक नहीं सकती है।
  5. कार्य कतार में डालने के लिए कॉल करने योग्य उपयोग सबमिट () विधि लेकिन कार्य कतार में डालने के लिए Runnable उपयोग निष्पादित () विधि।

यह महत्वपूर्ण है कि जाँच किए गए अपवाद पर जोर दिया जाए , न कि
RuntimeException

5

कॉल करने योग्य और रन करने योग्य दोनों एक दूसरे के समान हैं और धागे को लागू करने में उपयोग कर सकते हैं। रननेबल को लागू करने के मामले में आपको रन () विधि को लागू करना होगा लेकिन कॉल करने योग्य के मामले में आपको कॉल () विधि को लागू करने की आवश्यकता होगी , दोनों विधि समान तरीके से काम करती हैं लेकिन कॉल करने योग्य कॉल () विधि में अधिक लचीलापन होता है। उनके बीच कुछ अंतर है।

के बीच अंतर Runnable और प्रतिदेय below-- के रूप में

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

विधि हस्ताक्षर - Runnable->

public void run(){}

Callable->

public Object call(){}

2) रन करने योग्य रन () विधि के मामले में यदि कोई भी चेक किया गया अपवाद उत्पन्न होता है, तो आपको कोशिश पकड़ने वाले ब्लॉक से निपटने की आवश्यकता होगी , लेकिन कॉल करने योग्य कॉल () विधि के मामले में आप नीचे दिए गए अपवाद को फेंक सकते हैं।

 public Object call() throws Exception {}

3) Runnable विरासत से आता है जावा 1.0 संस्करण है, लेकिन प्रतिदेय में आया था जावा 1.5 के साथ संस्करण निष्पादनकर्ता ढांचा।

यदि आप Executers से परिचित हैं तो आपको Runnable के बजाय Callable का उपयोग करना चाहिए ।

उम्मीद है आप समझ गए होंगे।


2

Runnable (बनाम) Callable तब आता है जब हम Executer ढांचे का उपयोग कर रहे हैं।

ExecutorService एक उपप्रकार है Executor, जो दोनों Runnable और Callable कार्यों को स्वीकार करता है।

पहले मल्टी-थ्रेडिंग को 1.0 के बाद से इंटरफ़ेस का उपयोग करके प्राप्त किया जा सकता है , लेकिन यहां समस्या यह है कि थ्रेड कार्य को पूरा करने के बाद हम थ्रेड्स जानकारी एकत्र करने में असमर्थ हैं। डेटा एकत्र करने के लिए हम स्थैतिक क्षेत्रों का उपयोग कर सकते हैं।Runnable

उदाहरण प्रत्येक छात्र डेटा एकत्र करने के लिए थ्रेड्स अलग करें।

static HashMap<String, List> multiTasksData = new HashMap();
public static void main(String[] args) {
    Thread t1 = new Thread( new RunnableImpl(1), "T1" );
    Thread t2 = new Thread( new RunnableImpl(2), "T2" );
    Thread t3 = new Thread( new RunnableImpl(3), "T3" );

    multiTasksData.put("T1", new ArrayList() ); // later get the value and update it.
    multiTasksData.put("T2", new ArrayList() );
    multiTasksData.put("T3", new ArrayList() );
}

इस समस्या को हल करने के लिए उन्होंने 1.5 से पेश किया है जो एक परिणाम देता है और एक अपवाद फेंक सकता है।Callable<V>

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

    public interface Runnable {
    public void run();
    }
    
    public interface Callable<Object> {
        public Object call() throws Exception;
    }

ExecutorService को निष्पादित करने के लिए कार्यों को सौंपने के लिए कुछ अलग तरीके हैं ।

  • execute(Runnable task):void नए धागे को क्रेट करता है लेकिन मुख्य थ्रेड या कॉलर थ्रेड को ब्लॉक नहीं करता है क्योंकि यह विधि वापस आती है।
  • submit(Callable<?>):Future<?>submit(Runnable):Future<?>जब आप भविष्य का उपयोग कर रहे हों , तो नए धागे को काटता है और मुख्य धागे को ब्लॉक करता है । ()

Interfaces Runnable, Callable with Executor फ्रेमवर्क का उपयोग करने का उदाहरण।

class CallableTask implements Callable<Integer> {
    private int num = 0;
    public CallableTask(int num) {
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);

        return num;
    }
}
class RunnableTask implements Runnable {
    private int num = 0;
    public RunnableTask(int num) {
        this.num = num;
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);
    }
}
public class MainThread_Wait_TillWorkerThreadsComplete {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("Main Thread start...");
        Instant start = java.time.Instant.now();

        runnableThreads();
        callableThreads();

        Instant end = java.time.Instant.now();
        Duration between = java.time.Duration.between(start, end);
        System.out.format("Time taken : %02d:%02d.%04d \n", between.toMinutes(), between.getSeconds(), between.toMillis()); 

        System.out.println("Main Thread completed...");
    }
    public static void runnableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<?> f1 = executor.submit( new RunnableTask(5) );
        Future<?> f2 = executor.submit( new RunnableTask(2) );
        Future<?> f3 = executor.submit( new RunnableTask(1) );

        // Waits until pool-thread complete, return null upon successful completion.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
    public static void callableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<Integer> f1 = executor.submit( new CallableTask(5) );
        Future<Integer> f2 = executor.submit( new CallableTask(2) );
        Future<Integer> f3 = executor.submit( new CallableTask(1) );

        // Waits until pool-thread complete, returns the result.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
}

0

यह एक प्रकार का इंटरफ़ेस नामकरण सम्मेलन है जो कार्यात्मक प्रोग्रामिंग के साथ मेल खाता है

//Runnable
interface Runnable {
    void run();
}

//Action - throws exception
interface Action {
    void run() throws Exception;
}

//Consumer - consumes a value/values, throws exception
interface Consumer1<T> {
    void accept(T t) throws Exception;
}

//Callable - return result, throws exception
interface Callable<R> {
    R call() throws Exception;
}

//Supplier - returns result, throws exception
interface Supplier<R> {
    R get() throws Exception;
}

//Predicate - consumes a value/values, returns true or false, throws exception
interface Predicate1<T> {
    boolean test(T t) throws Exception;
}

//Function - consumes a value/values, returns result, throws exception
public interface Function1<T, R> {
    R apply(T t) throws Throwable;
}

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