Kā iestatīt taimeri, piemēram, uz 2 minūtēm, lai mēģinātu izveidot savienojumu ar datubāzi un pēc tam mest izņēmumu, ja rodas problēmas saistībā ar savienojumu?
Tātad atbildes pirmā daļa ir par to, kā darīt to, ko tēma prasa, jo tas bija veids, kā es to sākotnēji interpretēju, un dažiem cilvēkiem šķita noderīgi. Kopš tā laika jautājums tika precizēts, un es paplašināju atbildi, lai uz to atbildētu.
Timera iestatīšana
Vispirms ir jāizveido taimeris (es šeit izmantoju java.util
versiju):
import java.util.Timer;
..
Timer timer = new Timer();
Lai palaistu uzdevumu vienu reizi, veiciet šādas darbības:
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);
Lai uzdevums tiktu atkārtots pēc ilguma, jūs izdarītu:
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);
Uzdevuma pārtraukšanas laika iestatīšana
Lai konkrēti izdarītu to, kas uzdots precizētajā jautājumā, t. i., mēģinātu veikt uzdevumu noteiktu laika periodu, jūs varētu rīkoties šādi:
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();
}
Tas tiks izpildīts normāli ar izņēmumiem, ja uzdevums tiks pabeigts 2 minūšu laikā. Ja tas turpināsies ilgāk, tiks izmests TimeoutException.
Viena problēma ir tāda, ka, lai gan pēc divām minūtēm tiks parādīts TimeoutException, uzdevums faktiski turpinās darboties, lai gan, iespējams, datubāzes vai tīkla savienojums beigu beigās beigsies un pavedienā tiks izmests izņēmums. Taču jāapzinās, ka līdz tam var tikt patērēti resursi.
Labi, domāju, ka tagad saprotu jūsu problēmu. Jūs varat izmantot Future, lai mēģinātu kaut ko darīt, un pēc brīža, ja nekas nav noticis, izmantot timeout.
Piemēram:
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
}