Cum să setați un cronometru, să zicem pentru 2 minute, pentru a încerca să vă conectați la o bază de date, apoi să aruncați o excepție dacă există vreo problemă în conexiune?
Așadar, prima parte a răspunsului este cum să faci ceea ce cere subiectul, deoarece așa am interpretat inițial și câțiva oameni au părut să considere că este util. Întrebarea a fost de atunci clarificată și am extins răspunsul pentru a aborda acest aspect.
Setarea unui cronometru
Mai întâi trebuie să creați un Timer (eu folosesc aici versiunea java.util
):
import java.util.Timer;
..
Timer timer = new Timer();
Pentru a rula sarcina o singură dată, trebuie să faceți:
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);
Pentru ca sarcina să se repete după o anumită durată, trebuie să faceți:
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);
Facerea unui timeout pentru o sarcină
Pentru a face în mod specific ceea ce cere întrebarea clarificată, adică încercarea de a efectua o sarcină pentru o anumită perioadă de timp, ați putea face următoarele:
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();
}
Acest lucru se va executa în mod normal, cu excepții, dacă sarcina se finalizează în 2 minute. Dacă se execută mai mult de atât, se va arunca excepția TimeoutException.
O problemă este că, deși veți primi o excepție TimeoutException după cele două minute, activitatea va continua de fapt să ruleze, deși, probabil, o bază de date sau o conexiune de rețea va expira în cele din urmă și va arunca o excepție în firul de execuție. Dar fiți conștienți că ar putea consuma resurse până când se întâmplă acest lucru.
Bine, cred că acum înțeleg problema ta. Poți folosi un Future pentru a încerca să facă ceva și apoi să se oprească după un timp dacă nu s-a întâmplat nimic.
De exemplu:
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
}