2017-01-02 25 views
0

我想在特定的時間運行一項任務,例如每天晚上7點11分。 我試過下面這段代碼,但它不工作。如何計算ScheduledExecutorService的initialDelay#scheduleAtFixedRate

import java.util.Calendar; 
import java.util.Date; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

public class Task3 { 
    public static void main(String[] args) { 
     Runnable runnable = new Runnable() { 
      public void run() { 
       System.out.println(new Date()); 
       System.out.println("Hello !!"); 
      } 
     }; 

     Calendar calendar = Calendar.getInstance(); 
     long now = calendar.getTimeInMillis(); 
     calendar.set(Calendar.HOUR, 18); 
     calendar.set(Calendar.MINUTE, 11); 
     calendar.set(Calendar.SECOND, 0); 
     calendar.set(Calendar.MILLISECOND, 0); 
     ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); 
     service.scheduleAtFixedRate(runnable, calendar.getTimeInMillis(), 5, TimeUnit.SECONDS); 
    } 
} 

在上面的代碼中,我試圖運行從下午7點11分開始每天用5秒的間隔調度任務。但這並不像我預期的那樣。而且,如果我想在另一個條件下執行相同的任務,那麼應該只在特定日期執行任務,比如說每個星期二和星期三。

我在計算方法或其他東西的initialDelay參數時會出現某種錯誤嗎?

回答

1

方面評論:它可能會更簡單的使用ad hoc庫(如石英)。

initialDelay參數給出了運行任務之前等待的時間單位數。在你的情況下,你需要計算剩餘時間到7點11分。

因此,它可能看起來像:

long nextRun = calendar.getTimeInMillis(); 
long initialDelayMillis = nextRun - now; 
long oneDayMillis = 1000L * 60 * 60 * 24; 
service.scheduleAtFixedRate(runnable, initialDelayMillis, oneDayMillis, TimeUnit.MILLISECONDS); 

但這隻會處理基本情況。特別是它根本不會處理時鐘調整或DST。 「僅在星期二和星期三」說「並不容易」。

另一種方法是隻安排下一次運行並在可運行結束時重新安排它。這樣你可以更好地控制執行。但底線是:請參閱我的初始評論。

0

優選的是scheduledExecutorService。 但也許定時器也可以使用。用於擺動另一個計時器。

這裏有一個例子(timer和timerTask可以用cancel/purge來停止)。

import java.util.Calendar; 
import java.util.Date; 
import java.util.Timer; 
import java.util.TimerTask; 

public class TimeScheduleTest { 
    Timer timer = new Timer(); 
    public static void main(String[] args) { 
    new TimeScheduleTest().startApp(); 
    } 

private void startApp() { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.DAY_OF_WEEK,Calendar.TUESDAY); 
    calendar.set(Calendar.HOUR_OF_DAY, 7); 
    calendar.set(Calendar.MINUTE, 11); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MILLISECOND, 0); 
    timer.scheduleAtFixedRate(new StartTimer(), calendar.getTime(), 5000); 
} 

class StartTimer extends TimerTask { 
    public void run() { 
    System.out.println(new Date()); 
    System.out.println("Hello !!"); 
    } 
} 
}