पहले निष्पादक बनाएं।
आपके पास कई संभावनाएं हैं।
यदि मुझे लगता है कि आपके कार्य उनकी स्थिति ('NeedReschedule' या 'Completed' के साथ एक enum की तरह कुछ करने के लिए एक सरल इंटरफ़ेस लागू करते हैं), तो अपने कार्यों के लिए एक रैपर लागू करें (Runnable
लागू करना) जो कार्य करेगा और निष्पादन पैरामीटर के रूप में निष्पादक। यह रैपर उस कार्य को चलाएगा जो इसे बाध्य करता है, बाद में इसकी स्थिति की जांच करें, और यदि आवश्यक हो तो निष्पादक में स्वयं की प्रतिलिपि स्वयं की एक प्रतिलिपि करें।
वैकल्पिक रूप से, आप रैपर को सिग्नल करने के लिए एक निष्पादन तंत्र का उपयोग कर सकते हैं कि कार्य को पुन: निर्धारित किया जाना चाहिए। यह समाधान सरल है, इस अर्थ में कि इसे आपके लिए एक विशेष इंटरफ़ेस की आवश्यकता नहीं है, ताकि सरल Runnable
बिना किसी परेशानी के सिस्टम में फेंक दिया जा सके। हालांकि, अपवादों में अधिक गणना समय (ऑब्जेक्ट निर्माण, स्टैक ट्रेस इत्यादि) होता है।
अपवाद सिग्नलिंग तंत्र का उपयोग करके रैपर का एक संभावित कार्यान्वयन यहां दिया गया है। आपको RescheduleException
कक्षा Throwable
तक विस्तारित करने की आवश्यकता है, जिसे लपेटा हुआ रननेबल (इस सेटअप में कार्य के लिए अधिक विशिष्ट इंटरफ़ेस की आवश्यकता नहीं है) द्वारा निकाल दिया जा सकता है। आप एक अन्य उत्तर में प्रस्तावित एक सरल RuntimeException
का भी उपयोग कर सकते हैं, लेकिन आपको यह जानने के लिए संदेश स्ट्रिंग का परीक्षण करना होगा कि यह अपवाद है जिसका आप इंतजार कर रहे हैं।
public class TaskWrapper implements Runnable {
private final ExecutorService executor;
private final Runnable task;
public TaskWrapper(ExecutorService e, Runnable t){
executor = e;
task = t;
}
@Override
public void run() {
try {
task.run();
}
catch (RescheduleException e) {
executor.execute(this);
}
}
यहाँ एक बहुत ही सरल 200 लिपटे कार्यों बेतरतीब ढंग से ऊपर फायरिंग आवेदन एक पुनर्निर्धारित पूछ है।
class Task implements Runnable {
@Override
public void run(){
if (Maths.random() > 0.5)
throw new RescheduleException();
}
}
public class Main {
public static void main(String[] args){
ExecutorService executor = Executors.newFixedThreadPool(10);
int i = 200;
while(i--)
executor.execute(new TaskWrapper(executor, new Task());
}
}
तुम भी एक समर्पित धागा अन्य थ्रेड परिणाम (एक संदेश कतार का उपयोग) पर नजर रखने और पुनर्निर्धारित यदि आवश्यक हो सकता है, लेकिन आप अन्य समाधान की तुलना में एक धागा खो देते हैं,।
बस एक नया कार्य बनाएं जो वर्तमान के बराबर है और इसे कतार में डाल दें। वर्तमान कार्य को समाप्त करें – hoaz
@hoaz: क्या आप निष्पादक को कार्यों के अंदर से संदर्भित करते हैं? – Cratylus
@ क्रेटिलस - हाँ, यदि कार्य में निष्पादक को संदर्भ दिया गया है, तो यह स्वयं को फिर से कतारबद्ध कर सकता है। बस सुनिश्चित करें कि निष्पादक की लंबित कार्य कतार असंबद्ध है या आप अपने आप को मृत-लॉकिंग समाप्त कर सकते हैं। – jtahlborn