Java'da Zamanlayıcı nasıl ayarlanır?

Bir Veritabanına bağlanmayı denemek ve ardından bağlantıda herhangi bir sorun varsa istisna atmak için 2 dakika gibi bir Zamanlayıcı nasıl ayarlanır?

Çözüm

Cevabın ilk kısmı, konunun sorduğu şeyin nasıl yapılacağıdır, çünkü başlangıçta bu şekilde yorumladım ve birkaç kişi yararlı bulmuş gibi görünüyordu. Soru o zamandan beri açıklığa kavuşturuldu ve ben de bunu ele almak için cevabı genişlettim.

Zamanlayıcı ayarlama

Öncelikle bir Zamanlayıcı oluşturmanız gerekir (ben burada java.util sürümünü kullanıyorum):

import java.util.Timer;

..

Timer timer = new Timer();

Görevi bir kez çalıştırmak için yapmanız gerekenler:

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

Yapacağınız süreden sonra görevin tekrarlanmasını sağlamak için:

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

Görev zaman aşımına uğratılıyor

Özellikle açıklanan sorunun sorduğu şeyi yapmak için, yani belirli bir süre boyunca bir görevi yerine getirmeye çalışmak için aşağıdakileri yapabilirsiniz:

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

Bu, görev 2 dakika içinde tamamlanırsa istisnalar dışında normal şekilde yürütülür. Bundan daha uzun sürerse, TimeoutException fırlatılacaktır.

Bir sorun, iki dakika sonra bir TimeoutException almanıza rağmen, görev aslında çalışmaya devam edecektir, ancak muhtemelen bir veritabanı veya ağ bağlantısı sonunda zaman aşımına uğrayacak ve iş parçacığında bir istisna oluşturacaktır. Ancak bu gerçekleşene kadar kaynakları tüketebileceğini unutmayın.

Yorumlar (9)

Bunu kullanın

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

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

//Throw your exception
Yorumlar (10)

Tamam, sanırım sorununuzu şimdi anladım. Bir şey yapmaya çalışmak için bir Future kullanabilir ve hiçbir şey olmamışsa bir süre sonra zaman aşımına uğratabilirsiniz.

Örneğin:

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