第六章 Java ScheduledThreadPoolExecutor 示例


有多种方法可以在 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 Sc​​heduledFuture<?> 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 示例的全部内容。


原文链接:https://codingdict.com/