Wie kann man einen Timer einstellen, beispielsweise für 2 Minuten, um zu versuchen, eine Verbindung zu einer Datenbank herzustellen, und dann eine Ausnahme auslösen, wenn ein Verbindungsproblem vorliegt?
Lassen Sie das OP klären, ob sie die Aktion einfach mindestens 2 Minuten lang versuchen
möchten
Antworten:
280
Der erste Teil der Antwort ist also, wie man das macht, was das Thema verlangt, da ich es anfangs so interpretiert habe und einige Leute es als hilfreich empfanden. Die Frage wurde inzwischen geklärt und ich habe die Antwort erweitert, um dies zu beheben.
Timer einstellen
Zuerst müssen Sie einen Timer erstellen (ich verwende die java.utilVersion hier):
import java.util.Timer;
..
Timer timer =newTimer();
So führen Sie die Aufgabe aus, sobald Sie Folgendes tun würden:
timer.schedule(newTimerTask(){@Overridepublicvoid run(){// Your database code here}},2*60*1000);// Since Java-8
timer.schedule(()->/* your database code here */,2*60*1000);
So wiederholen Sie die Aufgabe nach der Dauer, die Sie ausführen würden:
timer.scheduleAtFixedRate(newTimerTask(){@Overridepublicvoid run(){// Your database code here}},2*60*1000,2*60*1000);// Since Java-8
timer.scheduleAtFixedRate(()->/* your database code here */,2*60*1000,2*60*1000);
Zeitüberschreitung für Aufgaben
Um genau das zu tun, was in der geklärten Frage gestellt wird, dh zu versuchen, eine Aufgabe für einen bestimmten Zeitraum auszuführen, können Sie Folgendes tun:
ExecutorService service =Executors.newSingleThreadExecutor();try{Runnable r =newRunnable(){@Overridepublicvoid run(){// Database task}};Future<?> f = service.submit(r);
f.get(2,TimeUnit.MINUTES);// attempt the task for two minutes}catch(finalInterruptedException e){// The thread was interrupted during sleep, wait or join}catch(finalTimeoutException e){// Took too long!}catch(finalExecutionException e){// An exception from within the Runnable task}finally{
service.shutdown();}
Dies wird mit Ausnahmen normal 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 die Task zwar nach zwei Minuten eine TimeoutException erhält, die Task jedoch weiterhin ausgeführt wird , obwohl vermutlich eine Datenbank- oder Netzwerkverbindung irgendwann eine Zeitüberschreitung aufweist und eine Ausnahme in den Thread auslöst. Beachten Sie jedoch, dass dies bis dahin Ressourcen verbrauchen kann.
Oh, ich denke, Sie haben mein Problem falsch verstanden. Ich muss wiederholt versuchen, jedes
Mal
Es tut mir leid, aber meine Anforderung ist, dass ich 2 Minuten Zeit geben möchte, um eine Verbindung zur Datenbank herzustellen, und dann wird nur eine Fehlermeldung ausgegeben. Es ist, als ob ich ein Zeitlimit festlegen möchte, um zu versuchen, eine Verbindung zur Datenbank
herzustellen
7
LESER VORSICHT: Diese Antwort ist offensichtlich falsch. Es legt einen Timer fest, der 2 Minuten wartet, und führt dann nach dieser 2-minütigen Verzögerung eine DB-Abfrage aus. Anschließend wird sie alle 2 Minuten immer wieder ausgeführt. Was es NICHT tut, ist, die DB-Abfrage sofort auszuführen und dann nach 2 Minuten auszufallen, was meiner Meinung nach die gestellte Frage ist (wie im Kommentar erläutert).
AgilePro
2
@ AgilePro Das war wahr. Ich habe die Frage nicht beantwortet, da sie schließlich angegeben wurde, und ich habe sie jetzt aktualisiert, um dies zu beheben.
Andrewmu
1
@ErnestasGruodis Die Kern-APIs listen den Konstruktor als öffentlich auf: docs.oracle.com/javase/7/docs/api/java/util/Timer.html#Timer () Möglicherweise haben Sie eine andere Timer-Klasse in Ihrem Klassenpfad - versuchen Sie es mit Java. util.Timer als Klasse.
Andrewmu
25
Benutze das
long startTime =System.currentTimeMillis();long elapsedTime =0L.while(elapsedTime <2*60*1000){//perform db poll/check
elapsedTime =(newDate()).getTime()- startTime;}//Throw your exception
hmm ... das würde technisch funktionieren, außer es deckt keine
Randfälle ab
1
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 falschem Kopf suggerieren.
AgilePro
1
@thecoshman - Die Timer-Implementierungen unterbrechen den DB-Vorgang NICHT, sobald er 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 weit verbreitetes Missverständnis, dass Sie einen "Timer" benötigen, um die Zeit zu bestimmen, aber Sie tun es 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
Angenommen, Sie müssen entweder die Verbindung zurückgeben oder nach genau zwei Minuten werfen. Dies funktioniert nicht. Dies wird der Fall sein, wenn Sie nach zwei Minuten des Verbindungsversuchs immer noch keine Verbindung hergestellt haben. In einer Situation, in der die Verbindungsprüfung beispielsweise zwei Wochen dauert, dauert es so lange, bis eine Ausnahme ausgelöst wird.
Thecoshman
14
Dies ist eigentlich ein sehr schlechter Codierungsstil, da die while-Schleife ständig läuft und nach Dingen sucht ... schlecht für die CPU und schlecht für die Akkulaufzeit.
Unendlich
11
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 eine Zeitüberschreitung, wenn nichts passiert ist.
Z.B:
FutureTask<Void> task =newFutureTask<Void>(newCallable<Void>(){@OverridepublicVoid call()throwsException{// Do DB stuffreturnnull;}});Executor executor =Executors.newSingleThreadScheduledExecutor();
executor.execute(task);try{
task.get(5,TimeUnit.SECONDS);}catch(Exception ex){// Handle your exception}
Ausnahme wird ausgelöst, aber das Programm wird nicht beendet. Bitte helfen Sie mir dabei.
Ankita
2
Sie können die ExecutorService-Klasse anstelle von Executor verwenden. Es hat die shutdown () -Methode, um den Executor zu stoppen.
Riten
1
Executoren schlucken ausgelöste Ausnahmen, die Sie in Ihrem Callable / Runnable nicht speziell behandeln. Wenn Ihr Runnable / Callable die Ausnahme selbst nicht abfängt und behandelt und Ihnen im Vergleich zu Ihrem Eigentümer zur Verfügung gestellt wird, müssen Sie den ScheduledExecutorService in eine Unterklasse unterteilen und afterExecute überschreiben (stellen Sie sicher, dass Sie super.afterExecute () aufrufen). Das zweite Argument für afterExecute ist das Throwable aus dem Runnable / Callable
Adam
3
new java.util.Timer().schedule(newTimerTask(){@Overridepublicvoid run(){System.out.println("Executed...");//your code here //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly }},1000*5,1000*5);
Kopieren Sie einfach den Schädling über den Code, es wird gut funktionieren. Ich habe zweimal "Zeit" angegeben, zum einen zum ersten Mal, um diesen Code auszuführen, und zum anderen für die Intervallzeit.
Antworten:
Der erste Teil der Antwort ist also, wie man das macht, was das Thema verlangt, da ich es anfangs so interpretiert habe und einige Leute es als hilfreich empfanden. Die Frage wurde inzwischen geklärt und ich habe die Antwort erweitert, um dies zu beheben.
Timer einstellen
Zuerst müssen Sie einen Timer erstellen (ich verwende die
java.util
Version hier):..
So führen Sie die Aufgabe aus, sobald Sie Folgendes tun würden:
So wiederholen Sie die Aufgabe nach der Dauer, die Sie ausführen würden:
Zeitüberschreitung für Aufgaben
Um genau das zu tun, was in der geklärten Frage gestellt wird, dh zu versuchen, eine Aufgabe für einen bestimmten Zeitraum auszuführen, können Sie Folgendes tun:
Dies wird mit Ausnahmen normal 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 die Task zwar nach zwei Minuten eine TimeoutException erhält, die Task jedoch weiterhin ausgeführt wird , obwohl vermutlich eine Datenbank- oder Netzwerkverbindung irgendwann eine Zeitüberschreitung aufweist und eine Ausnahme in den Thread auslöst. Beachten Sie jedoch, dass dies bis dahin Ressourcen verbrauchen kann.
quelle
Benutze das
quelle
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 eine Zeitüberschreitung, wenn nichts passiert ist.
Z.B:
quelle
quelle
[Android] wenn jemand Timer mit Java auf Android implementieren möchte .
quelle