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?
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.
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<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
}