2012-08-14 8 views
9

कभी-कभी दोहराए गए कार्य की अवधि इसकी अवधि से अधिक लंबी होती है (मेरे मामले में, यह एक समय में घंटों के लिए हो सकती है) । एक दोहराए गए कार्य के बारे में सोचें जो चलाने में 7 मिनट लगते हैं और हर 10 मिनट में चलने के लिए निर्धारित होता है, लेकिन कभी-कभी कुछ घंटों के लिए प्रत्येक रन के लिए 15 मिनट लगते हैं।जावा में चलने वाले एकल-थ्रेडेड दोहराए जाने वाले शेड्यूल को शेड्यूल करें, लेकिन पिछली रन समाप्त नहीं होने पर मौजूदा रन को छोड़ दें

टाइमर और अनुसूचित थ्रेडपूल एक्स्सेलर कक्षाओं में एक शेड्यूल है एटफिक्स्डरेट विधि जो आमतौर पर इस प्रकार की कार्यक्षमता के लिए उपयोग की जाती है। हालांकि, दोनों में विशेषता है कि वे 'पीछे आने पर पकड़ने की कोशिश करते हैं'। दूसरे शब्दों में, यदि कोई टिमर कुछ निष्पादनों के पीछे पड़ता है, तो यह काम की कतार तैयार करता है जो लगातार तब तक काम करेगा जब तक कि यह तब तक नहीं चलता जब तक कि कोई भी कार्य अधिक समय से नहीं लेता निर्दिष्ट अवधि। यदि पिछले रन पूरा नहीं हुआ है तो मैं वर्तमान निष्पादन को छोड़कर इस व्यवहार से बचना चाहता हूं।

मेरे पास एक समाधान है जिसमें पूल किए गए निष्पादक के बाद निष्पादन विधि के साथ गड़बड़ करना, देरी का पुनर्मूल्यांकन करना, और नई देरी के साथ चलने योग्य को पुन: निर्धारित करना शामिल है, लेकिन यह सोच रहा था कि कोई आसान तरीका है या यदि यह कार्यक्षमता पहले से मौजूद है कहीं एक आम पुस्तकालय। मुझे निश्चित अवधि के बजाय निश्चित देरी के साथ शेड्यूलिंग के बारे में पता है, लेकिन यह मेरे लिए काम नहीं करेगा क्योंकि कार्यों को अपने निश्चित समय पर निष्पादित करने का प्रयास करना महत्वपूर्ण है। क्या मेरे निष्पादन समाधान के बाद से कोई आसान विकल्प है?

+3

सरल है कि आपका कार्य जांचना है कि कोई अन्य उदाहरण पहले से चल रहा है, और यदि ऐसा है, तो तुरंत खुद को गोली मारो। –

+0

@ हॉट लिक्स: अनुसूचितExecutorService वास्तव में उन्हें समानांतर में नहीं चलाता है। –

+0

तो यहां मुख्य आवश्यकता क्या है? यह केवल ** और एक ** 10 मिनट के अंतराल पर हमेशा शुरू होता है, भले ही यह किसी को याद किया हो? यदि ऐसा है तो आप एक दर के बारे में बात नहीं कर रहे हैं। –

उत्तर

13

मुझे लगता है कि आप जो चाहते हैं वह लंबे समय से चलने वाले कार्य के लिए स्वयं अनुसूचित एक्सप्लोरर सेवा में नहीं चलने के लिए है, लेकिन पृष्ठभूमि धागे में। फिर निश्चित-दर कार्य हमेशा तेज़ी से पूरा हो जाएगा, क्योंकि इसका उपयोग केवल पृष्ठभूमि में वास्तविक कार्य शुरू करने के लिए किया जाता है (या नहीं, अगर यह अभी भी अंतिम समय से चल रहा है)।

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); 
final Runnable actualTask = null; 

executorService.scheduleAtFixedRate(new Runnable() { 
    private final ExecutorService executor = Executors.newSingleThreadExecutor(); 
    private Future<?> lastExecution; 
    @Override 
    public void run() { 
     if (lastExecution != null && !lastExecution.isDone()) { 
      return; 
     } 
     lastExecution = executor.submit(actualTask); 
    } 
}, 10, 10, TimeUnit.MINUTES); 
+0

मैंने पहले ही अपने प्रश्न में इस विकल्प का उल्लेख किया है। – jonderry

+0

@jonderry: क्षमा करें, आपकी आखिरी वाक्य को याद किया। मुझे कुछ अन्य विचार मिल गए हैं, यह सुनिश्चित नहीं है कि वे कोई क्लीनर होंगे या नहीं। –

+0

@jonderry: ठीक है मुझे लगता है कि मैंने जो नवीनतम सुझाव पोस्ट किया है वह एक अच्छा है। मैंने अपना जवाब साफ़ कर दिया, आप अन्य सुझावों के लिए संपादन इतिहास देख सकते हैं। –

1

समन्वयक कहा जाता है, एक तीसरी कक्षा बनाओ। कोऑर्डिनेटर में एक सिंक्रनाइज़ स्टार्टरिंग() विधि है जो सेट करने के लिए सही है और सत्य लौटाती है अगर कोई अन्य थ्रेड पहले से नहीं चल रहा था। सिंक्रनाइज़ स्टॉप राइजिंग विधि भी होनी चाहिए जो गलत सेट करने के लिए सेट है। यदि कोई रननेबल पहले से चल रहा है तो यह सच हो जाता है। आप इस वर्ग का एक उदाहरण बनाते हैं और आपके द्वारा बनाए गए सभी रननेबल्स का संदर्भ देते हैं। रननेबल की रन विधि में आप पहले स्टार्ट राइजिंग को कॉल करते हैं और यह सत्यापित करने के लिए रिटर्न की जांच करते हैं कि कोई दूसरा पहले से नहीं चल रहा है। अंत में ब्लॉक के अंदर से कोशिश करने के लिए कोशिश करें और अंत में कॉल रोकें।

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