有多种方法可以在 java 中安排任务。我们已经有Java timer来安排任务,但是 timers 任务的问题是您一次只能执行一个任务。因此,如果当前任务需要更长的时间,后续作业将被延迟。
在这种情况下,您可以使用 Java ScheduledThreadPoolExecutor。这个类是 Executor 框架的一部分,它提供了安排任务而不是立即执行任务的工具。 您可以使用三种方法来使用 ScheduledThreadPoolExecutor 来安排任务。
第 1 步:创建一个名为“RunnableTask.java”的可运行任务。
package org.arpit.java2blog;
import java.util.Date;
public class RunnableTask implements Runnable{
private String taskName;
public RunnableTask(String s){
this.taskName=s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" Start Time for "+taskName+" "+new Date());
// Process task here
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" End Time for "+taskName+" "+new Date());
}
@Override
public String toString(){
return this.taskName;
}
}
第2步:
package org.arpit.java2blog;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolMain {
public static void main(String[] args) throws InterruptedException {
System.out.println("Current Time = "+new Date());
// Created ScheduledThreadPoolExecutor object
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
for(int i=1; i<=3; i++){
Thread.sleep(2000);
RunnableTask task = new RunnableTask("Task "+i);
scheduledThreadPool.schedule(task,5, TimeUnit.SECONDS);
}
// Adding some delay
Thread.sleep(10000);
scheduledThreadPool.shutdown();
System.out.println("Completed all threads");
}
}
让我们更多地了解上述主要方法。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
ScheduledThreadPoolExecutor 在 Executors 类中也有名为 newScheduledThreadPool 的工厂方法,类似于 newFixedThreadPoolExecutor 和 newCachedThreadPoolExectuor。 您需要调用 schedule 方法来安排任务。 schedule 方法接受三个参数: public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit): Runnable command:表示要调度的任务。 长时间延迟:它表示您要安排任务的初始延迟。 TimeUnit 单位:延迟参数的时间度量。 如果您注意到, schedule 方法会返回 ScheduledFuture<?> 的对象,您可以使用它来获取已提交作业的状态。
我们还调用了scheduledThreadPool.shutdown(),shutdown()方法默认会等待提交的任务执行然后终止。您可以使用 setExecuteExistingDelayedTasksAfterShutdownPolicy() 更改此策略。
当你运行上面的程序时,你会得到下面的输出:
Current Time = Fri May 19 00:20:39 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:20:46 IST 2017
pool-1-thread-2 Start Time for Task 2 Fri May 19 00:20:48 IST 2017
pool-1-thread-3 Start Time for Task 3 Fri May 19 00:20:50 IST 2017
pool-1-thread-1 End Time for Task 1 Fri May 19 00:20:51 IST 2017
pool-1-thread-2 End Time for Task 2 Fri May 19 00:20:53 IST 2017
pool-1-thread-3 End Time for Task 3 Fri May 19 00:20:55 IST 2017
Completed all threads
ScheduledThreadPoolExecutor 的 scheduleAtFixedRate 示例:
ScheduledThreadPoolExecutor 的 scheduleAtFixedRate 用于在修复延迟后调度任务,然后定期执行该任务。 scheduleAtFixedRate 方法有四个参数: public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit) Runnable command:表示要调度的任务。 long initialDelay:它表示您要安排任务的初始延迟。 长周期:它表示您要重复任务的周期。 TimeUnit 单位:延迟参数的时间度量。 让我们做一些更改来调用 ScheduledThreadPoolMain 中的 scheduleAtFixedRate。
package org.arpit.java2blog;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("Current Time = "+new Date());
// Created ScheduledThreadPoolExecutor object
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
for(int i=1; i<=3; i++){
Thread.sleep(2000);
RunnableTask task = new RunnableTask("Task "+i);
scheduledThreadPool.scheduleAtFixedRate(task,5,10,TimeUnit.SECONDS);
}
// Adding some delay
Thread.sleep(15000);
scheduledThreadPool.shutdown();
while(!scheduledThreadPool.isTerminated()){
//wait for all tasks to finish
}
System.out.println("Completed all threads");
}
}
当你运行上面的程序时,你会得到下面的输出:
Current Time = Fri May 19 00:56:29 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:56:36 IST 2017
pool-1-thread-2 Start Time for Task 2 Fri May 19 00:56:38 IST 2017
pool-1-thread-3 Start Time for Task 3 Fri May 19 00:56:40 IST 2017
pool-1-thread-1 End Time for Task 1 Fri May 19 00:56:41 IST 2017
pool-1-thread-2 End Time for Task 2 Fri May 19 00:56:43 IST 2017
pool-1-thread-3 End Time for Task 3 Fri May 19 00:56:45 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:56:46 IST 2017
pool-1-thread-2 Start Time for Task 2 Fri May 19 00:56:48 IST 2017
pool-1-thread-3 Start Time for Task 3 Fri May 19 00:56:50 IST 2017
pool-1-thread-1 End Time for Task 1 Fri May 19 00:56:51 IST 2017
pool-1-thread-2 End Time for Task 2 Fri May 19 00:56:53 IST 2017
pool-1-thread-3 End Time for Task 3 Fri May 19 00:56:55 IST 2017
Completed all threads
如果仔细观察输出:
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:56:36 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:56:46 IST 2017
一旦任务 1 开始,下一个任务会在 scheduleAtFixedRate 方法中提供的 10 秒后安排。
ScheduledThreadPoolExecutor 的 scheduleWithFixedDelay 示例:
ScheduledThreadPoolExecutor 的 scheduleWithFixedDelay 用于在初始延迟后调度一个任务,然后在前一个任务完成后以固定延迟执行任务。 让我们做一些更改来调用 ScheduledThreadPoolMain 中的 scheduleWithFixedDelay。
package org.arpit.java2blog;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("Current Time = "+new Date());
// Created ScheduledThreadPoolExecutor object
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
for(int i=1; i<=3; i++){
Thread.sleep(2000);
RunnableTask task = new RunnableTask("Task "+i);
scheduledThreadPool.scheduleWithFixedDelay(task,5,10,TimeUnit.SECONDS);
}
// Adding some delay
Thread.sleep(30000);
scheduledThreadPool.shutdown();
while(!scheduledThreadPool.isTerminated()){
//wait for all tasks to finish
}
System.out.println("Completed all threads");
}
}
Current Time = Fri May 19 00:20:39 IST 2017
Current Time = Fri May 19 00:50:53 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:51:00 IST 2017
pool-1-thread-2 Start Time for Task 2 Fri May 19 00:51:02 IST 2017
pool-1-thread-3 Start Time for Task 3 Fri May 19 00:51:04 IST 2017
pool-1-thread-1 End Time for Task 1 Fri May 19 00:51:05 IST 2017
pool-1-thread-2 End Time for Task 2 Fri May 19 00:51:07 IST 2017
pool-1-thread-3 End Time for Task 3 Fri May 19 00:51:09 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:51:15 IST 2017
pool-1-thread-2 Start Time for Task 2 Fri May 19 00:51:17 IST 2017
pool-1-thread-3 Start Time for Task 3 Fri May 19 00:51:19 IST 2017
pool-1-thread-1 End Time for Task 1 Fri May 19 00:51:20 IST 2017
pool-1-thread-2 End Time for Task 2 Fri May 19 00:51:22 IST 2017
pool-1-thread-3 End Time for Task 3 Fri May 19 00:51:24 IST 2017
Completed all threads
如果仔细观察输出:
pool-1-thread-1 End Time for Task 1 Fri May 19 00:51:05 IST 2017
pool-1-thread-1 Start Time for Task 1 Fri May 19 00:51:15 IST 2017
一旦任务 1 结束,下一个任务会在 scheduleWithFixedDelay 方法中提供的 10 秒延迟后安排。
这就是 Java ScheduledThreadPoolExecutor 示例的全部内容。
|