2015-12-16 13 views
13

Belirli bir süre sonra "bir şey yapacak" bir geri sayım sayacı ayarlama satırları boyunca, bir şeyler yapmayı geciktirmek istiyorum.Bir görevi bir defa çalışacak şekilde nasıl zamanlarım?

Beklerken çalışmasını sağlamak için programımın kalanını istiyorum, bu yüzden benim bir dakikalık gecikme içeriyordu kendi Thread yapma çalıştı: Bu çalıştı iken

public class Scratch { 
    private static boolean outOfTime = false; 

    public static void main(String[] args) { 
     Thread countdown = new Thread() { 
      @Override 
      public void run() { 
       try { 
        // wait a while 
        System.out.println("Starting one-minute countdown now..."); 
        Thread.sleep(60 * 1000); 

        // do the thing 
        outOfTime = true; 
        System.out.println("Out of time!"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 
     countdown.start(); 

     while (!outOfTime) { 
      try { 
       Thread.sleep(1000); 
       System.out.println("do other stuff here"); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 


, daha-veya- daha az, bunu yapmanın daha iyi bir yolu olmalıydı.

Bazı arama yaptıktan sonra, ben bu gibi bir sürü soru buldum ama gerçekten ben yapmaya çalışıyorum hitap etmeyebilir:

Bu karmaşaya ihtiyacım yok ted; Programın geri kalanı hala çalışmasına izin verirken belirli bir süre sonra tek bir şey yapmak istiyorum.

Tek seferlik bir görevi "bir şey yapmak" için zamanlamayı nasıl yapmalıyım?

cevap

16

gelecekteki görevleri planlamak için iyi bir yol olarak kullanılan java.util.Timer birlikte, yerine java.util.concurrent paketindeki sınıfları kullanmak artık tercih edilir.

Özellikle bir gecikme sonrasında (veya belirli aralıklarla yürütmek için, ancak bu soruyla ilgisi olmayan) bir komut çalıştırmak için tasarlanmış bir ScheduledExecutorService vardır.

Bu

oluşturur ve belirli bir süre sonra etkin hale gelen bir tek adımlı bir işlem gerçekleştiren bir schedule(Runnable, long, TimeUnit) yöntemi vardır. Bir ScheduledExecutorService böyle programınızı yeniden yazabilirsiniz kullanma


: Eğer şeyler bu şekilde yaparak almak güzel şeyler

import java.util.concurrent.*; 

public class Scratch { 
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
    public static void main(String[] args) { 
     System.out.println("Starting one-minute countdown now..."); 
     ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() { 
      @Override 
      public void run() { 
       // do the thing 
       System.out.println("Out of time!"); 
      }}, 1, TimeUnit.MINUTES); 

     while (!countdown.isDone()) { 
      try { 
       Thread.sleep(1000); 
       System.out.println("do other stuff here"); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     scheduler.shutdown(); 
    } 
} 

One ScheduledFuture<?> nesne schedule() aramasını geri almak olduğunu .

Bu, fazladan boolean değişkeninden kurtulmanızı ve işin doğrudan çalışıp çalışmadığını doğrudan kontrol etmenizi sağlar.

Artık, cancel() yöntemini çağırarak beklemek istemiyorsanız, zamanlanan görevi de iptal edebilirsiniz.


bir ExecutorService lehine Timer kullanmaktan kaçınmak için nedenlerle Java Timer vs ExecutorService? bakınız.Bu planlanan yürütücü bir veya birkaç dakikada bir çalıştırılacak

+0

. Benimki sadece bir kez kaçmak ve çıkmak istiyorum. – qualebs

+0

@qualebs Bu örnekte, eylem yalnızca bir kez çalışacaktır. Zamanlama() 'yöntemine geçirilen süre, eylemin yürütülmesinden önceki gecikme olur. – azurefrog