2009-12-21 14 views
7

मुझे यह समस्या है, मेरे पासजावा: सिंगल थ्रेड शेड्यूल्ड एक्स्सेलर और java.util.concurrent.RejectedExecutionException

private ScheduledExecutorService executor = 
    Executors.newSingleThreadScheduledExecutor(); 

और कार्य है जो हर 50 मिलीलीसेकंड बनाया गया है:

executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS); 

myTask कभी-कभी पूरा होने में कुछ समय लगता है (जैसे 2-3 सेकंड या उससे अधिक), लेकिन newSingleThreadScheduledExecutor गारंटी देता है कि अगला निर्धारित MyTask वर्तमान तक पूरा होने तक प्रतीक्षा करेगा।

हालांकि, मुझे समय-समय पर यह त्रुटि मिलती है:

निष्पादित करें: java.util.concurrent.RejectedExecutionException

मुझे क्या करना चाहिए? धन्यवाद

+0

कृपया क्या yyou द्वारा "समय-समय पर" मतलब के बारे में अधिक विशिष्ट हो। यह अपवाद केवल निष्पादक सेवा पर 'execute()' को कॉल करने के पल में फेंक दिया जाना चाहिए। –

+0

वास्तव में, RejectedExecutionException executor.scheduleAtFixedRate() –

+0

@Andrey द्वारा फेंकने योग्य है, तो आप हमें काफी अधिक जानकारी देने के लिए, अपवाद दिखा एक स्टैक ट्रेस के साथ शुरू की जरूरत है। –

उत्तर

11

देखें विचार करें कि निष्पादक कर रही है। यह आपके निर्देशों के अनुसार, हर 50 मिलीसेकंड में एक ही कार्य चला रहा है। इस कार्य को मानने के लिए 50 मिलीसेकंड से कम समय लगता है, तो सबकुछ ठीक है। हालांकि, हर बार इसे चलाने में 2-3 सेकंड लगते हैं। जब ऐसा होता है, तो निष्पादक अभी भी हर 50 मिलीसेकंड निष्पादित करने का प्रयास करता है, लेकिन क्योंकि इसमें केवल एक ही धागा है, यह उन निष्पादन को अस्वीकार नहीं कर सकता है, जो आपके लंबे समय तक चलने वाले कार्य को जारी करते समय ट्रिगर किए जा रहे हैं। यह आपके द्वारा देखे गए अपवाद का कारण बनता है।

आपके पास दो विकल्प यह (आप एक ही धागे से रहना चाहते हैं कल्पना करते हुए) ठीक करने के लिए है:

  1. उपयोग scheduleWithFixedDelay बजाय scheduleAtFixedRate। यदि आप सावधानीपूर्वक जावाडोक पढ़ते हैं, तो आप देखेंगे कि scheduleWithFixedDelay एक कार्य को खत्म करने और अगले की शुरुआत के बीच 50 मिलीसेकंड का इंतजार करेगा, इसलिए यह कभी भी "ओवरलैप" नहीं होगा, भले ही उनमें से एक लंबा समय लगे। इसके विपरीत, scheduleAtFixedRate प्रत्येक 50 मिलीसेकंड निष्पादित करने का प्रयास करेगा, इस पर ध्यान दिए बिना कि प्रत्येक व्यक्ति कितना समय लेता है।

  2. बदलें रास्ता है कि निष्पादक निष्पादित करने के लिए विफलताओं को संभालती है।डिफॉल्ट एक अपवाद लॉग करना है, लेकिन आप इसे अनदेखा करने के लिए कह सकते हैं, उदाहरण के लिए। java.util.concurrent.RejectedExecutionHandler के उप-वर्गों पर एक नज़र डालें, उदाहरण के लिए DiscardPolicy, जो केवल उस कार्य को चुपचाप छोड़ देता है जिसे चलाया नहीं जा सकता है। आप फैक्ट्री क्लास का उपयोग करने के बजाय सीधे ScheduledThreadPoolExecutor का निर्माण करके और कन्स्ट्रक्टर में हैंडलर में गुजरकर इनका उपयोग कर सकते हैं।

मुझे संदेह है कि विकल्प (1) वह है जो आप चाहते हैं।

+0

धन्यवाद! यह काम करता है – Andrey

+3

@skaffman: scheduleAtFixedRate: वास्तव में यह वास्तव में क्या आप में 1. :) जावाडोक कहा के विपरीत है इस कार्य के किसी भी निष्पादन इसकी अवधि से अधिक समय लेता, तो उसके बाद फांसी देर से शुरू हो सकता है, लेकिन समवर्ती पर अमल नहीं होगा – radio

4

यह अपवाद फेंक दिया जाएगा जब या तो:

  1. आप बंद निर्वाहक
  2. अपना काम कतार या अधिकतम धागे के लिए निर्वाहक के सीमा को पार किया गया है।

मुझे लगता है कि बाद वाला हो रहा है। जब आप अपना कार्य निष्पादित करते हैं और इसमें काफी समय लगता है तो बाद के अनुसूचित कार्यों को नहीं चलाया जा सकता क्योंकि पूल में पर्याप्त धागे उपलब्ध नहीं हैं।

कोई एक:

  1. उपयोग एक बड़ा पूल आकार का उपयोग करें या cachedThreadPool
  2. बदलें उदाहरण के लिए उपयोग ThreadPoolExecutor.CallerRunsPolicy
  3. लंबे समय कार्यों और रन चल रहा है के लिए एक अलग निर्वाहक बनाने के लिए अस्वीकृति नीति का उपयोग ये आपके निर्धारित कार्य से हैं। वास्तव में आप एक ही निष्पादक उदाहरण का उपयोग करके ऐसा कर सकते हैं जिससे आप पूल आकार बढ़ा सकें।

भी ThreadPoolExecutor javadoc

+0

मेरी स्थिति में cachedThreadPool का उपयोग कैसे करें? execor.scheduleAtFixedRate (myTask, 0, 50, TimeUnit.MILLISECONDS); ThreadPoolExecutor अस्वीकृति नीति को बदलना कैसे संभव है? धन्यवाद – Andrey

-1

जावा 7 के साथ उन दोनों को इंतजार करेंगे जब तक पहले निष्पादन के लिए तैयार है और फिर अगले प्रारंभ करें!

जांच यहाँ:
http://download.java.net/jdk7/archive/b123/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

या यहाँ:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

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