2010-10-28 34 views
114

Wie setze ich einen Timer, sagen wir für 2 Minuten, um zu versuchen, eine Verbindung zu einer Datenbank herzustellen und dann eine Ausnahme auszulösen, wenn ein Problem in der Verbindung besteht?Wie setze ich einen Timer in Java?

+1

Coul das OP klar, wenn sie die Aktion für mindestens 2 Minuten einfach versuchen wollen, oder wenn die Ausnahme jetzt später die zwei Minuten geworfen werden müssen, auch wenn ein Verbindungsversuch im Gange ist – thecoshman

Antwort

224

Also der erste Teil der Antwort ist, wie zu tun, was das Thema fragt, wie dies war, wie ich es zunächst interpretiert und ein paar Leute schien hilfreich zu finden. Die Frage wurde seither geklärt und ich habe die Antwort darauf erweitert.

einen Timer

erste Einstellung benötigen Sie einen Timer erstellen (Ich verwende die java.util Version hier):

import java.util.Timer; 

..

Timer timer = new Timer(); 

die auszuführen Aufgabe, die Sie einmal tun würden:

timer.schedule(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000); 

Um die Aufgabe zu wiederholen, nachdem die Dauer haben Sie tun würde:

timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000, 2*60*1000); 

Einen Task Timeout

speziell zu tun, was die geklärte Frage stellt, dass eine neue Aufgabe für ein auszuführen versucht, Bei gegebener Zeit können Sie Folgendes tun:

ExecutorService service = Executors.newSingleThreadExecutor(); 

try { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      // Database task 
     } 
    }; 

    Future<?> f = service.submit(r); 

    f.get(2, TimeUnit.MINUTES);  // attempt the task for two minutes 
} 
catch (final InterruptedException e) { 
    // The thread was interrupted during sleep, wait or join 
} 
catch (final TimeoutException e) { 
    // Took too long! 
} 
catch (final ExecutionException e) { 
    // An exception from within the Runnable task 
} 
finally { 
    service.shutdown(); 
} 

Dies wird normalerweise mit Ausnahmen ausgeführt, wenn die Aufgabe innerhalb von 2 Minuten abgeschlossen ist . Wenn es länger läuft, wird die TimeoutException ausgelöst.

Ein Problem ist, dass, obwohl Sie einen Timeout nach den 2 Minuten bekommen, die Aufgabe tatsächlich weiterhin laufen, obwohl vermutlich eine Datenbank oder Netzwerkverbindung wird schließlich eine Ausnahme im Thread einer Zeitüberschreitung und werfen. Aber sei dir bewusst, dass es Ressourcen verbrauchen kann, bis das passiert.

+0

Oh ich denke, du hast mein Problem falsch, ich muss immer wieder versuchen, mit der Datenbank bis 2 Minuten zu verbinden – Ankita

+1

Ich aktualisierte meine Antwort zu wiederholen alle 2 Minuten – andrewmu

+0

Es tut mir leid, aber meine Anforderung ist, dass ich 2 Minuten geben möchte, um die Datenbank und dann zu verbinden wird nur einige Fehlermeldung zu werfen.Es ist wie ich ein Zeitlimit zu versuchen, um eine Verbindung zur Datenbank – Ankita

9

Ok, ich glaube ich verstehe dein Problem jetzt. Sie können eine Zukunft verwenden, um zu versuchen, etwas zu tun und dann nach einer Weile Timeout, wenn nichts passiert ist.

Z. B .:

FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() { 
    @Override 
    public Void call() throws Exception { 
    // Do DB stuff 
    return null; 
    } 
}); 

Executor executor = Executors.newSingleThreadScheduledExecutor(); 
executor.execute(task); 

try { 
    task.get(5, TimeUnit.SECONDS); 
} 
catch(Exception ex) { 
    // Handle your exception 
} 
+0

Ausnahme wird ausgelöst, aber das Programm wird nicht beendet. Bitte helfen Sie mir durch. – Ankita

+2

Sie können stattdessen ExecutorService-Klasse verwenden Der Executor hat eine shutdown() - Methode, um den Executor zu stoppen – Rites

+1

Executors werden geworfene Exceptions verschlucken, die Sie nicht speziell in Callable/Runnable behandeln Wenn Ihre Runnable/Callable die Exception selbst nicht abfängt und handhabt Wenn Sie das Programm gegen Sie bereitstellen, müssen Sie den ScheduledExecutorService ableiten und nachExecute überschreiben (stellen Sie sicher, dass Sie super.afterExecute()) aufrufen.Das zweite Argument für afterExecute ist das von Runnable/Callable zu übersetzende – adam

6

Wie den Timer zu stoppen?Stopp und wieder spielen, wenn in diesem Code etwas tun

timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000, 2*60*1000); 

Als ich die Verwendung timer.cancel();

es stoppen, aber wenn in der Nähe der Form und öffnen Sie sie erneut die Ausnahme

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Timer already cancelled. 
    at java.util.Timer.sched(Timer.java:354) 
    at java.util.Timer.scheduleAtFixedRate(Timer.java:296) 
    at View.Electronic_Meeting.this_componentShown(Electronic_Meeting.java:295) 
    at View.Electronic_Meeting.access$000(Electronic_Meeting.java:36) 
    at View.Electronic_Meeting$1.componentShown(Electronic_Meeting.java:85) 
    at java.awt.AWTEventMulticaster.componentShown(AWTEventMulticaster.java:162) 
    at java.awt.Component.processComponentEvent(Component.java:6095) 
    at java.awt.Component.processEvent(Component.java:6043) 
    at java.awt.Container.processEvent(Container.java:2041) 
    at java.awt.Component.dispatchEventImpl(Component.java:4630) 
    at java.awt.Container.dispatchEventImpl(Container.java:2099) 
    at java.awt.Component.dispatchEvent(Component.java:4460) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
17

Verwendung geworfen wird diese

long startTime = System.currentTimeMillis(); 
long elapsedTime = 0L. 

while (elapsedTime < 2*60*1000) { 
    //perform db poll/check 
    elapsedTime = (new Date()).getTime() - startTime; 
} 

//Throw your exception 
+1

hmm ... this würde technisch funktionieren, außer es deckt keine Fälle ab, in denen die Zeit abläuft, während Sie eine DB-Umfrage durchführen, w hich kann vom OP benötigt werden – thecoshman

+0

Dies ist die einzig richtige Antwort. Es läuft auf einem einzelnen Thread und berechnet die Endzeit ohne Drift. Die Verwendung einer TimerTask ist in diesem Fall genau das Falsche. Ich bin überrascht, wie viele Beispiele auf StackOverflow diese Art von falsch gelenkten Dingen vorschlagen. – AgilePro

+1

@thecoshman - die Timer-Implementierungen unterbrechen die DB-Operation NICHT, wenn sie gerade ausgeführt wird, und dies auch nicht. In jedem Fall können Sie nur die Zeit steuern, zu der Sie den DB-Vorgang starten. Es gibt ein allgemeines Missverständnis, dass Sie einen "Timer" brauchen, um Dinge zu messen, aber Sie nicht. Sie müssen nur etwas tun, und indem Sie die aktuelle Zeit verwenden, stellen Sie sicher, dass Sie es nicht zu lange tun. – AgilePro

1
new java.util.Timer().schedule(new TimerTask(){ 
     @Override 
     public void run() { 
      System.out.println("Executed..."); 
      //your code here 
      //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly 
     } 
    },1000*5,1000*5); 
+0

kopieren Sie einfach Pest über Code, es wird gut funktionieren. Ich habe zweimal die Zeit gegeben, zuerst ist es das erste Mal, diesen Code auszuführen, und zweitens ist für Intervallzeit. –