2009-03-12 12 views
11

मैं जावा डॉक्स में इसे देखा: ScheduledAtFixedRate, यह कहता हैशेड्यूल किए गए एक्सप्लोरर सेवा का उपयोग करके किसी कार्य को फिर से निर्धारित कैसे करें?

कार्य एक अपवाद का सामना करना पड़ता के किसी भी निष्पादन, बाद में फांसी दबा रहे हैं, तो

मैं ऐसा नहीं करना चाहता मेरे आवेदन में यहां तक ​​कि यदि मैं एक अपवाद देखता हूं तो भी मैं हमेशा के बाद के निष्पादन होने और जारी रखना चाहता हूं। मैं इस व्यवहार को ScheduledExecutorService से कैसे प्राप्त कर सकता हूं।

+1

उठाया गया है continiuerunning होगा समाधान [CosmoCode ब्लॉग में वर्णित ] (http://www.cosmocode.de/en/blog/schoenborn/2009-12/17-uncaught-exceptions-in-scheduled-tasks) – Chobicus

+0

_CosmoCode blog_ ** ब्लॉक ** में समाधान (भविष्य का उपयोग करके। प्राप्त करें(); '), जो 'निष्पादक' द्वारा प्रदान किए गए असीमित निष्पादन के बिंदु के खिलाफ है। – user454322

उत्तर

7

चारों ओर Callable.call विधि या आज़माएं/कैच के साथ Runnable.run विधि ...

जैसे:

public void run() 
{ 
    try 
    { 
     // ... code 
    } 
    catch(final IOException ex) 
    { 
     // handle it 
    } 
    catch(final RuntimeException ex) 
    { 
     // handle it 
    } 
    catch(final Exception ex) 
    { 
     // handle it 
    } 
    catch(final Error ex) 
    { 
     // handle it 
    } 
    catch(final Throwable ex) 
    { 
     // handle it 
    } 
} 

ध्यान दें कि क्या संकलक तुम भी बताता है के अलावा और कुछ को पकड़ने (मेरे नमूने में IOException) एक अच्छा विचार नहीं है, लेकिन कुछ बार हैं, और यह उनमें से एक की तरह लगता है, अगर आप इसे ठीक से संभालते हैं तो यह काम कर सकता है।

याद रखें कि त्रुटि जैसी चीजें बहुत खराब हैं - वीएम स्मृति से बाहर हो गया है ... इसलिए सावधान रहें कि आप उन्हें कैसे संभालें (यही कारण है कि मैंने उन्हें पकड़ने के बजाय अपने स्वयं के हैंडलरों में अलग कर दिया (अंतिम थ्रोबल पूर्व) और कुछ और नहीं)।

+0

ध्यान दें कि यदि आप दोहराने वाले निर्धारित कार्य में फेंकने योग्य नहीं हैं और ओओएमई घटित होता है, तो आप इसके बारे में कभी भी पता नहीं लगाएंगे (जब तक कि शेड्यूल्यूफ्यूचर पर कुछ कॉल नहीं हो रहा है() निष्पादन निष्पादन –

+0

लॉग इन करें तो ठीक है ... अनुमान लगाएं आपको ... ick :-) मैं सत्यापित करूँगा और फिर मेरा उत्तर अपडेट करूँगा - thx – TofuBeer

+0

विशेष थ्रेड को समाप्त करने के कारण बाद में निष्पादन रोक रहा है? यदि थ्रेड पूल का आकार 1 से अधिक है, जो अधिकतर सत्य है, तो शेड्यूल किए गए एक्सप्लोरर सेवा कार्यान्वयन के लिए एक अलग थ्रेड का उपयोग करके कार्य को चलाने का प्रयास करना क्यों संभव नहीं है? – RRM

1

मुझे एक ही समस्या थी। मैंने यह भी कोशिश की कि रन() विधि के भीतर ब्लॉक करने का प्रयास करें लेकिन यह काम नहीं करता है।

तो मैं ने कुछ किया अब तक काम कर रहा है:

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.LinkedBlockingQueue; 

public class Test2 { 

    static final ExecutorService pool = Executors.newFixedThreadPool(3); 

    static final R1 r1 = new R1(); 
    static final R2 r2 = new R2(); 

    static final BlockingQueue deadRunnablesQueue = new LinkedBlockingQueue<IdentifiableRunnable>(); 

    static final Runnable supervisor = new Supervisor(pool, deadRunnablesQueue); 

    public static void main(String[] args) { 
     pool.submit(r1); 
     pool.submit(r2); 
     new Thread(supervisor).start(); 
    } 

    static void reSubmit(IdentifiableRunnable r) { 
     System.out.println("given to an error, runnable [" + r.getId() 
       + "] will be resubmited"); 
     deadRunnablesQueue.add(r); 
    } 

    static interface IdentifiableRunnable extends Runnable { 
     String getId(); 
    } 

    static class Supervisor implements Runnable { 
     private final ExecutorService pool; 
     private final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue; 

     Supervisor(final ExecutorService pool, 
       final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue) { 
      this.pool = pool; 
      this.deadRunnablesQueue = deadRunnablesQueue; 
     } 

     @Override 
     public void run() { 
      while (true) { 
       IdentifiableRunnable r = null; 
       System.out.println(""); 
       System.out 
         .println("Supervisor will wait for a new runnable in order to resubmit it..."); 
       try { 
        System.out.println(); 
        r = deadRunnablesQueue.take(); 
       } catch (InterruptedException e) { 
       } 
       if (r != null) { 
        System.out.println("Supervisor got runnable [" + r.getId() 
          + "] to resubmit "); 
        pool.submit(r); 
       } 
      } 
     } 
    } 

    static class R1 implements IdentifiableRunnable { 
     private final String id = "R1"; 
     private long l; 

     @Override 
     public void run() { 
      while (true) { 
       System.out.println("R1 " + (l++)); 
       try { 
        Thread.currentThread().sleep(5000); 
       } catch (InterruptedException e) { 
        System.err.println("R1 InterruptedException:"); 
       } 
      } 
     } 

     public String getId() { 
      return id; 
     } 
    } 

    static class R2 implements IdentifiableRunnable { 
     private final String id = "R2"; 
     private long l; 

     @Override 
     public void run() { 
      try { 
       while (true) { 
        System.out.println("R2 " + (l++)); 
        try { 
         Thread.currentThread().sleep(5000); 
        } catch (InterruptedException e) { 
         System.err.println("R2 InterruptedException:"); 
        } 
        if (l == 3) { 
         throw new RuntimeException(
           "R2 error.. Should I continue to process ? "); 
        } 
       } 
      } catch (final Throwable t) { 
       t.printStackTrace(); 
       Test2.reSubmit(this); 
      } 
     } 

     public String getId() { 
      return id; 
     } 
    } 

} 

आप Test2.reSubmit (यह) बाहर टिप्पणी करने के लिए देखने के लिए कि यह बिना, आर 2 काम करना बंद होगा कोशिश कर सकते हैं। जब किसी को भी कॉल runnable.run() कोई अपवाद नहीं फेंक दिया जाता है,

import com.jcabi.log.VerboseRunnable; 
Runnable runnable = new VerboseRunnable(
    Runnable() { 
    public void run() { 
     // do business logic, may Exception occurs 
    } 
    }, 
    true // it means that all exceptions will be swallowed and logged 
); 

अब:

+0

स्पष्टीकरण: वास्तव में ScheduledExecutorService रन() विधि के भीतर प्रयास ब्लॉक के साथ काम करता है। उपरोक्त उदाहरण इसके बजाय execorService पर आधारित है। – Rodolfo

+0

अपना कोड साझा करने के लिए धन्यवाद। हालांकि यह एक अच्छा उदाहरण है, जटिल लग रहा है। – user454322

2

jcabi-log से VerboseRunnable वर्ग है, जो रैपिंग TofuBeer ने सुझाव दिया करता है की कोशिश करो। इसके बजाए, वे निगल गए हैं और लॉग इन हैं (एसएलएफ 4 जे के लिए)।

+0

अच्छा, 'अपवाद' VerboseRunnable' का उपयोग करके निगल लिया गया है, इसलिए बाद के कार्यों को निष्पादित किया जाएगा। – user454322

1

यदि आप चाहते हैं कि बाद में निष्पादन हो और अपवाद के बाद भी जारी रखें, तो यह कोड काम करना चाहिए।

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();  

Runnable task = new Runnable() {  
    @Override 
    public void run() { 
    try{ 
     System.out.println(new Date() + " printing"); 
     if(true) 
     throw new RuntimeException(); 

    } catch (Exception exc) { 
     System.out.println(" WARN...task will continiue"+ 
      "running even after an Exception has araised"); 
    } 
    }  
}; 

executor.scheduleAtFixedRate(task, 0, 3, TimeUnit.SECONDS); 

तो एक ThrowableException के अलावा अन्य हुआ है आप बाद में फांसी निष्पादित हो नहीं चाहते हो सकता है।

यहाँ उत्पादन

शुक्र नवंबर 23 12:09:38 JST 2012 मुद्रण
_WARN ... कार्य होगा एक अपवाद के बाद भी continiuerunning उठाया गया है
शुक्र नवंबर 23 12:09:41 है जेएसटी 2012 प्रिंटिंग
_WARN ... कार्य को अपरिपक्व करने के बाद भी
शुक्र नवम्बर 23 12:09:44 जेएसटी 2012 प्रिंटिंग
_WARN ...काम के बाद भी एक अपवाद उठाया गया है मैं पसंद
शुक्र नवंबर 23 12:09:47 JST 2012 मुद्रण
_WARN ... कार्य continiuerunning जाएगा के बाद भी एक अपवाद

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