Executors框架之ScheduledExecutorService实现定时任务

Posted 52liming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Executors框架之ScheduledExecutorService实现定时任务相关的知识,希望对你有一定的参考价值。

一、简介

An ExecutorService that can schedule commands to run after a given delay, or to execute periodically.
(ExecutorService可以安排命令在给定的延迟后运行或定期执行。)

The schedule methods create tasks with various delays and return a task object that can be used to cancel or check execution. The scheduleAtFixedRate and scheduleWithFixedDelay methods create and execute tasks that run periodically until cancelled.
(调度方法会创建具有各种延迟的任务,并返回可用于取消或检查执行的任务对象。 scheduleAtFixedRate和scheduleWithFixedDelay方法创建并执行定期运行的任务,直到被取消为止。
)

Commands submitted using the Executor.execute(java.lang.Runnable) and ExecutorService submit methods are scheduled with a requested delay of zero. Zero and negative delays (but not periods) are also allowed in schedule methods, and are treated as requests for immediate execution.
(使用Executor.execute(java.lang.Runnable)和ExecutorService提交方法提交的命令的计划延迟为零。调度方法中还允许零延迟和负延迟(但不允许使用周期),并将其视为立即执行的请求。
)

All schedule methods accept relative delays and periods as arguments, not absolute times or dates. It is a simple matter to transform an absolute time represented as a Date to the required form. For example, to schedule at a certain future date, you can use: schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS). Beware however that expiration of a relative delay need not coincide with the current Date at which the task is enabled due to network time synchronization protocols, clock drift, or other factors. The Executors class provides convenient factory methods for the ScheduledExecutorService implementations provided in this package.
(所有调度方法都接受相对延迟和周期作为参数,而不是绝对时间或日期作为参数。将代表日期的绝对时间转换为所需的形式很简单。例如,要计划在某个将来的日期进行计划,可以使用:schedule(task,date.getTime()-System.currentTimeMillis(),TimeUnit.MILLISECONDS)。但是请注意,由于网络时间同步协议,时钟漂移或其他因素,相对延迟的到期时间不必与启用任务的当前日期一致。 Executors类为此程序包中提供的ScheduledExecutorService实现提供了方便的工厂方法。
)

(jdk7 doc , translate by google )

二、两个常用定时任务

1.

创建并执行一个周期性操作,该操作将在给定的初始延迟后首先启用,然后在给定的时间段内启用;即后执行将开始 在initialDelay然后在initialDelay +周期,然后 在initialDelay + 2 *周期,依此类推。

ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

2. ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

创建并执行一个周期性操作,该操作将在给定的初始延迟后首先启用,然后在一个执行的终止与下一个执行的开始之间具有给定的延迟。

3. ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)

创建并执行一次操作,该操作在给定的延迟后变为启用状态。

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
System.out.println("一次性的延迟任务, 10S 后执行");
executorService.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("一次性延迟任务");
    }
}, 10L, SECONDS);
        

4. ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)

创建并执行ScheduledFuture,该ScheduledFuture在给定的延迟后变为启用状态。

三、示例代码

class PrintControl {
    private final SimpleDateFormat SDF = new SimpleDateFormat("hh:mm:ss");

    /**
     * @param int corePoolSize 线程池中最小的线程数, 无任务时保持, 任务过多时可以超出这个值
     */


    private final ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
//    private final ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1, Executors.defaultThreadFactory());

    /**
     * 给定延迟的打印任务
     * 以固定的延迟时间(delay)去执行任务
     */
    public void printForDelay() {
        Runnable print = () -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("ScheduledWithFixedDelay" + SDF.format(new Date()));
        };

        /**
         * @param Runnable command
         * @param long initialDelay
         * @param long delay
         * @param TimeUnit unit
         */
        scheduled.scheduleWithFixedDelay(print, 0L, 5L, SECONDS);
    }

    /**
     * 定期去执行打印任务
     * 以固定的周期(period)去执行任务
     */
    public void printForRate() {
        Runnable print = () -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("ScheduledAtFixedRate" + SDF.format(new Date()));
        };

        /**
         * @param Runnable command
         * @param long initialDelay
         * @param long period
         * @param TimeUnit unit
         */
        scheduled.scheduleAtFixedRate(print, 0L, 5L, SECONDS);
    }


}

class PrintThreadFactory implements ThreadFactory {

    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r, "PrintThreadFactory");
    }
}

四、通过ThreadFactory 指定任务线程名称

五、有条件的结束任务

六、参考

以上是关于Executors框架之ScheduledExecutorService实现定时任务的主要内容,如果未能解决你的问题,请参考以下文章

什么是Executors框架?

什么是 Executors 框架?

Executor框架Executors工厂类

什么是 Executors 框架?

什么是Executors框架?

JAVA线程池 之 Executors