क्यों भविष्य .isDone() executorService.sutdown() के बाद होना चाहिए।

यह काम कर सकता है:

Future<Integer> submit1 = executorService.submit(callable);
executorService.shutdown();
while (submit1.isDone()){
   System.out.println(submit1.get());
}

लेकिन जब मैंने इस लाइन पर टिप्पणी की:

Future<Integer> submit1 = executorService.submit(callable);
//executorService.shutdown();
while (submit1.isDone()){
   System.out.println(submit1.get());
}

यह किसी भी परिणाम को प्रिंट नहीं कर सकता है।

-1
张卓鹏 9 सितंबर 2019, 15:58
क्या आपको अपवाद मिलता है? यह क्या बताता है?
 – 
Selaron
9 सितंबर 2019, 16:02
धन्यवाद, मैंने इस समस्या को हल कर लिया है।
 – 
张卓鹏
11 सितंबर 2019, 14:24

2 जवाब

सबसे बढ़िया उत्तर

आपको पहली बार में submit1.isDone() को कॉल नहीं करना चाहिए, और निश्चित रूप से while लूप में नहीं। चूंकि Future.get() एक ब्लॉकिंग कॉल है, while() भाग को हटाने पर आपको दोनों से समान व्यवहार प्राप्त होगा।

दूसरे मामले में आपको कुछ भी मुद्रित नहीं होने का कारण यह है कि कॉल करने योग्य को समाप्त करने का मौका नहीं मिला है, इसलिए while की स्थिति झूठी है।

shutdown() के बाद आप जिसे कर सकते हैं कॉल ExecutorService.awaitTermination() है। यह सभी कार्यों को पूरा करने के लिए दिए गए समय तक प्रतीक्षा करेगा। यदि आप नहीं चाहते कि कार्य समाप्त हो जाएं, तो आप shutdownNow() पर कॉल कर सकते हैं।

1
Kayaman 9 सितंबर 2019, 16:06
आपके उत्तर के लिए धन्यवाद, तो, isDone() सत्य लौटाता है जब तक कि मैं get() निष्पादित नहीं करता? मुझे लगता है कि मैं समझता हूं कि, यह get() कोण के बाद है, फिर isDone() सत्य लौटाता है। NOT isDone() वह सत्य लौटाता है जो आप प्राप्त कर सकते हैं() परिणाम।
 – 
张卓鹏
9 सितंबर 2019, 16:15
नहीं, isDone() कार्य पूरा होने पर सत्य लौटाता है। विशेष मामलों को छोड़कर आपको इसे कॉल नहीं करना चाहिए। बस पूरे while लूप को हटा दें। आपको isDone() को कॉल करने की आवश्यकता नहीं है, बस get() को कॉल करें। रिजल्ट आने तक यह ब्लॉक रहेगा।
 – 
Kayaman
9 सितंबर 2019, 16:17
1
ओह, मैं समझता हूं कि isDone() एक अवरुद्ध विधि नहीं है, यह बस प्राप्त करें() एक अवरुद्ध विधि है! आपका बहुत बहुत धन्यवाद ! आपका दिन शुभ हो !
 – 
张卓鹏
9 सितंबर 2019, 16:20

क्योंकि जब आप .shutdown() को कॉल करते हैं, तो थ्रेड की स्थिति बदल जाएगी, जिससे isDone रिटर्न सही हो जाता है। ThreadPoolExecutor कार्यान्वयन को देखें कि यह आपके थ्रेड स्थिति को कैसे बदलता है:

public void shutdown() {
    //...
    tryTerminate();
}


/**
 * Transitions to TERMINATED state if either (SHUTDOWN and pool
 * and queue empty) or (STOP and pool empty). 
 * ....
 * ....
 */
final void tryTerminate() {
....
}

और isDone() दस्तावेज़ कहता है कि यह विधि सामान्य समाप्ति, अपवाद या रद्दीकरण के कारण सही हो जाती है। इसलिए:

1) आपने कॉल करने योग्य सबमिट किया

2) आपने प्रक्रिया को बंद कर दिया है, इसलिए इसकी स्थिति अब समाप्त हो गई है

3) क्या हो गया रिटर्न सही है, आप देख सकते हैं।

अन्य मामलों में, आपका कॉल करने योग्य कभी समाप्त नहीं होता है, एक अपवाद फेंकता है या रद्द कर दिया जाता है जो हमेशा गलत होता है।

0
cmlonder 9 सितंबर 2019, 16:12
मैं यह कहना चाहता था कि थ्रेडपूल का tryTerminate फ़ंक्शन पहले से सबमिट किए गए थ्रेड के टर्मिनेशन सिग्नल को कॉल करके थ्रेड की स्थिति बदल देगा।
 – 
cmlonder
9 सितंबर 2019, 16:29
यह भी सच नहीं है। सबसे पहले, आप थ्रेड सबमिट नहीं करते हैं, आप कार्य सबमिट करते हैं। जब आप थ्रेडपूल को बंद करते हैं, तो यह नए कार्यों को स्वीकार करने से इंकार कर देगा, लेकिन पुराने को समाप्त कर देगा। निष्क्रिय वर्कर थ्रेड्स (यदि कोई हों) को जगाया जाता है ताकि वे सामान्य रूप से बंद हो सकें। अगर कोई काम नहीं करना है तो tryTerminate() विधि थ्रेडपूल को बंद कर देती है, लेकिन यह सक्रिय रूप से वर्कर थ्रेड्स (जैसे shutdownNow().
 – 
Kayaman
9 सितंबर 2019, 16:48