2012-02-23 10 views
5

में ThreadPoolExecutor के साथ अस्वीकृत एक्सेक्यूशन अपवाद को कैसे संभालें जावा में ThreadPoolExecutor का उपयोग करते समय RejectedExecutionException को संभालने का सबसे अच्छा तरीका क्या है?जावा

मैं यह सुनिश्चित करना चाहता हूं कि सबमिट किए गए कार्य को अनदेखा नहीं किया जाना चाहिए और निश्चित रूप से निष्पादित किया जाना चाहिए। अभी तक कार्य पूरा करने के लिए कोई कठिन वास्तविक समय आवश्यकता नहीं है।

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

खुश होंगे अगर लोग अपने अनुभव साझा कर सकें।

while(executor.getQueue().remainingCapacity <= 0){ 
// keep looping 
Thread.sleep(100); 
}; 
//if the loop exits ,indicates that we have space in the queue hence 
//go ahead and add to the queue 
executor.execute(new ThreadInstance(params)); 
+0

यदि एक से अधिक धागे ऐसा करने की कोशिश कर रहे हैं तो यह दौड़ की स्थिति पैदा करेगा। यह एक सीपीयू भी जला देगा जिसका अर्थ यह हो सकता है कि निष्पादक के लिए कतार को साफ़ करना अधिक समय लगता है। जैसे अगर योजक और निष्पादक के लिए केवल एक सीपीयू है, तो यह विनाशकारी हो सकता है। –

+0

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

+0

सोना, यहां तक ​​कि थोड़े समय के लिए (यहां तक ​​कि 1 - 10 एमएस) भी इससे बेहतर नहीं है। 100 एमएस भी एक अच्छा मूल्य है। यह ठीक है अगर आपके पास केवल एक प्रकाशन धागा है। –

उत्तर

3

मैं आपकी कतार का व्यवहार बदलूंगा। जैसे

public class MyBlockingQueue<E> extends ArrayBlockingQueue<E> { 
    private final long timeoutMS; 

    public MyBlockingQueue(int capacity, long timeoutMS) { 
     super(capacity); 
     this.timeoutMS = timeoutMS; 
    } 

    @Override 
    public boolean offer(E e) { 
     try { 
      return super.offer(e, timeoutMS, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e1) { 
      Thread.currentThread().interrupt(); 
      return false; 
     } 
    } 
} 

यह छोड़ने से पहले कतार को निकालने का इंतजार करेगा।

+0

कैंट मैं बस कुछ ऐसा करता हूं (execor.getQueue()। शेष क्षमता <= 0) {// लूपिंग रखें}; // यदि लूप निकलता है, तो इंगित करता है कि हमारे पास कतार में स्थान है इसलिए // आगे बढ़ें और कतार execor.execute (नया थ्रेड इंस्टेंस (पैराम्स)) में जोड़ें; यह ऐरेब्लॉकिंगक्यूयू का अपना उदाहरण बनाने के बिना एक समाधान प्रतीत होता है। – Neeraj

+0

बीमार मेरे प्रश्न में कोड जोड़ें। यहाँ लगता है। – Neeraj

+1

यदि आप करते हैं तो आपके पास दौड़ की स्थिति है। इस बात की कोई गारंटी नहीं है कि एक और थ्रेड एक ही चीज करने की कोशिश कर रहे कतार को भर नहीं सकता है। आपको अपनी खुद की ArrayBlockingQueue बनाने की ज़रूरत नहीं है, आप मेरी प्रतिलिपि बना सकते हैं। ;) –

2

आप अपने थ्रेड पूल विवश है केवल समवर्ती धागे की एक निश्चित संख्या (आम तौर पर एक अच्छी बात है) की अनुमति देने के लिए, तो आवेदन किसी भी तरह push- करने की जरूरत है:

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

एक समान स्थिति भारी लोड के तहत एक वेब सर्वर है। एक क्लाइंट कनेक्ट करता है, वेब सर्वर को 503 - सेवा अनुपलब्ध (आमतौर पर एक अस्थायी स्थिति) वापस करनी चाहिए और ग्राहक निर्णय लेता है कि इसके बारे में क्या करना है।