2017-01-02 2 views
0

Я хочу запустить задачу в определенное время, скажем, в 7.11pm каждый день. Я пробовал следующий фрагмент кода, но он не работает.Как рассчитать initialDelay для ScheduledExecutorService # 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

Боковой комментарий: вероятно, было бы проще использовать специальную библиотеку (например, кварц).

Параметр 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

Предпочтительным будет запланированная служба ExecutorService. Но, возможно, таймер тоже можно использовать. Для качания другого таймера.

Здесь пример (таймер и timerTask можно остановить с отменой/очисткой).

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 !!"); 
    } 
} 
} 
Смежные вопросы