Wie setzt man einen Timer in Java?

Wie man einen Timer, sagen wir für 2 Minuten, um zu versuchen, eine Verbindung zu einer Datenbank dann werfen Ausnahme, wenn es ein Problem in Verbindung ist?

Lösung

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 zu finden, hilfreich. Die Frage wurde seitdem geklärt und ich habe die Antwort erweitert, um darauf einzugehen.

Einstellen eines Timers

Zuerst müssen Sie einen Timer erstellen (ich verwende hier die Version java.util):

import java.util.Timer;

..

Timer timer = new Timer();

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

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

Um die Aufgabe nach der Dauer zu wiederholen, würden Sie Folgendes tun:

timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void 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);

Timeout für eine Aufgabe

Um genau das zu tun, wonach die geklärte Frage fragt, nämlich zu versuchen, eine Aufgabe für eine bestimmte Zeitspanne auszuführen, könnten 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 normal mit Ausnahmen ausgeführt, wenn die Aufgabe innerhalb von 2 Minuten abgeschlossen wird. Läuft sie länger, wird die TimeoutException geworfen.

Ein Problem ist, dass, obwohl Sie nach den zwei Minuten eine TimeoutException erhalten, die Aufgabe tatsächlich weiterläuft, obwohl vermutlich eine Datenbank- oder Netzwerkverbindung irgendwann eine Zeitüberschreitung verursacht und eine Ausnahme im Thread auslöst. Aber seien Sie sich bewusst, dass bis dahin Ressourcen verbraucht werden können.

Kommentare (9)

Verwenden Sie 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
Kommentare (10)

Ok, ich glaube, ich verstehe Ihr Problem jetzt. Du kannst einen Future verwenden, der versucht, etwas zu tun und dann nach einer Weile einen Timeout macht, wenn nichts passiert ist.

Z.B.:

FutureTask task = new FutureTask(new Callable() {
  @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
}
Kommentare (3)