Автор оригинала: Pankaj Kumar.
Добро пожаловать в пример планировщика Java. Сегодня мы рассмотрим ScheduledExecutorService
и его класс реализации ScheduledThreadPoolExecutor
пример.
Планировщик Java ScheduledExecutorService
Иногда нам нужно выполнять задачу периодически или с определенной задержкой. Java предоставляет класс таймера, с помощью которого мы можем достичь этого, но иногда нам нужно выполнять аналогичные задачи параллельно. Таким образом, создание нескольких объектов таймера будет накладными расходами для системы, и лучше иметь пул потоков запланированных задач.
Java обеспечивает реализацию пула запланированных потоков через ScheduledThreadPoolExecutor
класс, реализующий ScheduledExecutorService
интерфейс. ScheduledExecutorService определяет методы контракта для планирования задачи с различными параметрами.
Некоторое время назад я написал сообщение о Java ThreadPoolExecutor , где я использовал класс Executors для создания пула потоков. Класс Executors также предоставляет заводские методы для создания ScheduledThreadPoolExecutor , где мы можем указать количество потоков в пуле.
Пример планировщика Java
Допустим, у нас есть простой управляемый класс, как показано ниже.
Допустим, у нас есть простой управляемый класс, как показано ниже.
package com.journaldev.threads; import java.util.Date; public class WorkerThread implements Runnable{ private String command; public WorkerThread(String s){ this.command=s; } @Override public void run() { System.out.println(Thread.currentThread().getName()+" Start. Time = "+new Date()); processCommand(); System.out.println(Thread.currentThread().getName()+" End. Time = "+new Date()); } private void processCommand() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public String toString(){ return this.command; } }
Это простой управляемый класс, выполнение которого занимает около 5 секунд.
Давайте рассмотрим простой пример, в котором мы запланируем выполнение рабочего потока с задержкой в 10 секунд. Мы будем использовать класс исполнителей newScheduledThreadPool(int corePoolSize)
метод, который возвращает экземпляр ScheduledThreadPoolExecutor
. Вот фрагмент кода из класса Executors.
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
Ниже приведен пример нашей программы планировщика java, использующей реализацию ScheduledExecutorService
и ScheduledThreadPoolExecutor
.
package com.journaldev.threads; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPool { public static void main(String[] args) throws InterruptedException { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); //schedule to run after sometime System.out.println("Current Time = "+new Date()); for(int i=0; i<3; i++){ Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); scheduledThreadPool.schedule(worker, 10, TimeUnit.SECONDS); } //add some delay to let some threads spawn by scheduler Thread.sleep(30000); scheduledThreadPool.shutdown(); while(!scheduledThreadPool.isTerminated()){ //wait for all tasks to finish } System.out.println("Finished all threads"); } }
Когда мы запускаем приведенный выше пример программы планировщика java, мы получаем следующий вывод, подтверждающий, что задачи выполняются с задержкой в 10 секунд.
Current Time = Tue Oct 29 15:10:03 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 15:10:14 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 15:10:15 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 15:10:16 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 15:10:19 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 15:10:20 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 15:10:21 IST 2013 Finished all threads
Обратите внимание, что все методы schedule()
возвращают экземпляр Запланированное будущее
, который мы можем использовать для получения информации о состоянии потока и времени задержки потока.
ScheduledFuture расширяет интерфейс будущего, подробнее о них читайте в примере вызываемого будущего Java .
В ScheduledExecutorService есть еще два метода, которые предоставляют возможность запланировать периодическое выполнение задачи.
ScheduledExecutorService scheduleAtFixedRate(выполняемая команда,длительный начальный срок,длительный период,единица измерения времени)
Мы можем использовать метод ScheduledExecutorService scheduleAtFixedRate для планирования выполнения задачи после начальной задержки, а затем с заданным периодом.
Период времени начинается с начала первого потока в пуле, поэтому, если вы указываете период в 1 секунду, а ваш поток выполняется в течение 5 секунд, следующий поток начнет выполняться, как только первый рабочий поток завершит свое выполнение.
Например, если у нас есть такой код:
for (int i = 0; i < 3; i++) { Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); // schedule task to execute at fixed rate scheduledThreadPool.scheduleAtFixedRate(worker, 0, 10, TimeUnit.SECONDS); }
Затем мы получим результат, как показано ниже.
Current Time = Tue Oct 29 16:10:00 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:10:01 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 16:10:02 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 16:10:03 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 16:10:06 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 16:10:07 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 16:10:08 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:10:11 IST 2013 pool-1-thread-4 Start. Time = Tue Oct 29 16:10:12 IST 2013
ScheduledExecutorService scheduleWithFixedDelay(выполняемая команда,длительное начальное время,длительная задержка,единица измерения времени)
ScheduledExecutorService scheduleWithFixedDelay Метод может использоваться для запуска периодического выполнения с начальной задержкой, а затем выполнения с заданной задержкой. Время задержки начинается с момента завершения выполнения потока. Итак, если у нас есть код, как показано ниже:
for (int i = 0; i < 3; i++) { Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); scheduledThreadPool.scheduleWithFixedDelay(worker, 0, 1, TimeUnit.SECONDS); }
Затем мы получим результат, как показано ниже.
Current Time = Tue Oct 29 16:14:13 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:14:14 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 16:14:15 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 16:14:16 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 16:14:19 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 16:14:20 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:14:20 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 16:14:21 IST 2013 pool-1-thread-4 Start. Time = Tue Oct 29 16:14:21 IST 2013
Это все для примера планировщика java. Мы также узнали о потоке ScheduledExecutorService и ScheduledThreadPoolExecutor. Вам следует ознакомиться с другими статьями о многопоточности в Java .
Рекомендации: