2013-07-02 9 views
6

मेरे पास Futures का एक सेट है जो Callable s को Executor पर सबमिट करके बनाया गया है। छद्म कोड:फ्यूचर्स के बैच को पूरा करने के लिए प्रतीक्षा करते समय टाइमआउट?

for all tasks 
    futures.add(executor.submit(new callable(task))) 

अब मैं सभी पूर्ण होने तक सभी एनयूटर इंतजार करना चाहता हूं। मुझे पता है कि मैं Future#get(timeout) पर कॉल कर सकता हूं लेकिन अगर मैं लूप में अपने सभी वायदा के लिए अनुक्रमिक रूप से कॉल करता हूं तो टाइम्सआउट जोड़ना शुरू हो जाता है। छद्म कोड:

for all futures 
    future.get(timeout) 

get परिणाम जब तक समय समाप्त के साथ ब्लॉक तैयार है। इसलिए, यदि पहली बार टाइमआउट से पहले पूरा हो जाता है और दूसरा टाइमआउट से पहले भी पूरा हो जाता है और इसलिए पूरे निष्पादन समय पर number of futures * timeouttimeout के बजाय सबसे अधिक है।

इसलिए, मैं एक ऐसी विधि की तलाश में हूं जो Future एस और एक टाइमआउट की सूची स्वीकार करता है, सभी समानांतर में चलता है और फिर भविष्य के परिणामों का संग्रह देता है। कोई विचार?

+0

यह पूरी तरह से स्पष्ट नहीं है। आप उन कार्यों के साथ क्या करना चाहते हैं जो टाइमआउट की समयसीमा समाप्त होने पर पूरा नहीं हुआ है? क्या आप चाहते हैं कि उन्हें रद्द किया जाए या जारी रखने की अनुमति दी जाए? –

+0

उन्हें रद्द किया जाना चाहिए। इसके अलावा, किसी भी तरह मुझे यह जानने की जरूरत है कि कौन से लोग पूरा हुए और कौन नहीं। मुझे लगता है कि मैं वायदा पर एक बार फिर से उत्साहित हो सकता हूं और उन सभी पर 'isDone' का आह्वान कर सकता हूं। –

उत्तर

5

आप ExecutorService.invokeAll उपयोग कर सकते हैं:

पर क्रियान्वित दिया कार्यों, उनकी स्थिति धारण वायदा और परिणामों की एक सूची लौट रहा है जब सभी पूर्ण या समय समाप्त समाप्त हो रहा है, जो भी पहले हो। Future.isDone() लौटाई गई सूची के प्रत्येक तत्व के लिए सच है। वापसी पर, जो कार्य पूरा नहीं हुए हैं वे रद्द कर दिए गए हैं। ध्यान दें कि एक पूरा कार्य सामान्य रूप से या अपवाद फेंक कर समाप्त हो सकता है। इस प्रक्रिया के परिणाम प्रगति पर होने पर दिए गए संग्रह को संशोधित किया गया है, तो इस विधि के परिणाम अपरिभाषित हैं।


आप पहले से ही Future रों है कि आप पर नजर रखने की जरूरत है और invokeAll उपयोग नहीं कर सकते, तो आप बस समय समाप्ति खुद के माप सकते हैं। छद्म कोड:

long endTime = System.currentTimeMillis() + timeoutMS; 
for(f : futures) 
    f.get(Math.max(0, endTime - System.currentTimeMillis()), TimeUnit.MILLISECONDS); 

इस तरह आप ज्यादा से ज्यादा अवधि कि जब तक आप अपने समय समाप्ति तक पहुँचने के लिए छोड़ दिया है प्रत्येक भविष्य दे।

+0

'execorService.invokeAll' लगता है कि मैं क्या कर रहा हूं, धन्यवाद। उन सभी वायदाओं के लिए जो समय पर पूरा नहीं हुए थे 'रद्द है == सत्य', ठीक है (इस तरह मैं जावाडोक की व्याख्या करता हूं)? अपवाद के साथ 'भविष्य' पूरा होने पर मुझे कैसे पता चलेगा? "ध्यान दें कि एक पूरा कार्य सामान्य रूप से या अपवाद फेंकने से समाप्त हो सकता है" - यह मुश्किल है ... –

+1

@ मार्सेलस्टोर हां, वायदा जो पूरा नहीं हुए थे रद्द कर दिए गए हैं ('रद्द है() == सत्य')। फिर आप यह निर्धारित करते हैं कि 'भविष्य' के साथ क्या हुआ जब आप इसे कॉल करते हैं ['get()'] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html# % 28% 2 9 प्राप्त करें) ('invokeAll' रिटर्न के बाद)। यदि 'get'' रद्दीकरण अपवाद 'फेंकता है, तो आप जानते हैं कि इसे रद्द कर दिया गया है। यदि यह 'निष्पादन अपवाद' फेंकता है, तो इसका अर्थ है 'भविष्य' अपवाद के साथ पूरा हुआ, और अपवाद 'निष्पादन एक्सेप्शन.getCause() 'के माध्यम से सुलभ है। –

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

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