Hoe een timer instellen in Java?

Hoe stel je een timer in, bijvoorbeeld voor 2 minuten, om te proberen verbinding te maken met een database en dan een uitzondering te maken als er een probleem is met de verbinding?

Oplossing

Dus het eerste deel van het antwoord is hoe te doen wat het onderwerp vraagt, omdat dit was hoe ik het aanvankelijk interpreteerde en een paar mensen het nuttig leken te vinden. De vraag werd sindsdien verduidelijkt en ik'heb het antwoord uitgebreid om dat aan te pakken.

Instellen van een timer

Eerst moet je een Timer maken (ik'gebruik hier de java.util versie):

import java.util.Timer;

..

Timer timer = new Timer();

Om de taak eenmaal uit te voeren zou je doen:

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);

Om de taak te laten herhalen na de tijdsduur zou je doen:

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);

Een taak time-out maken

Om specifiek te doen wat de verduidelijkte vraag vraagt, namelijk proberen een taak gedurende een bepaalde tijd uit te voeren, zou je het volgende kunnen doen:

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();
}

Dit zal normaal worden uitgevoerd met uitzonderingen als de taak binnen 2 minuten is voltooid. Als het langer duurt dan dat, zal de TimeoutException worden gegooid.

Een probleem is dat hoewel je'een TimeoutException krijgt na de twee minuten, de taak eigenlijk zal blijven lopen, hoewel vermoedelijk een database- of netwerkverbinding uiteindelijk zal uitlopen en een exceptie in de thread zal werpen. Maar wees ervan bewust dat het resources kan verbruiken tot dat gebeurt.

Commentaren (9)

Gebruik dit.

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

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

//Throw your exception
Commentaren (10)

Ok, ik denk dat ik je probleem nu begrijp. Je kunt een Future gebruiken om te proberen iets te doen en dan na een tijdje timeout als er niets gebeurd is.

Bijv:

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
}
Commentaren (3)