文档章节

Java并发编程高级篇(七):使用执行器周期性地执行任务

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2017/03/02 09:36
字数 870
阅读 31
收藏 0

我们已经学习了如何利用执行器框架提供的ThreadPoolExecutor类的线程池来执行任务,而不用我们手动去创建线程。同时我们也学习了,如何使用ScheduledThreadPoolExecutor类来延迟执行任务,如果你要指定任务执行的时间点,你只需要计算当前时间与目标时间的差值,把这个差值作为延迟时间即可实现定时执行任务。

接下来,如果我们想要周期性地执行一个任务,该怎么办呢。同样,我们可以使用ScheduledThreadPoolExecutor类来实现这个功能。

首先创建一个任务类,并实现Runnable接口。在call()方法中打印任务执行时间。

import java.util.Date;

/**
 * 新建Task类并实现Runnable接口
 *
 * 打印当前任务名+执行时间
 *
 * Created by hadoop on 2016/11/3.
 */
public class Task implements Runnable {
    private String name;

    public Task(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.printf("%s: Starting at : %s\n", name, new Date());
    }
}

然后我们创建主线程类。使用Executors工厂类的newScheduledThreadPoolExecutor来创建线程执行器,并调用它的scheduleAtFixedRate方法来周期性地执行任务,注意这个周期任务执行方法与schedule()延迟执行方法不同的是,它只能接受Runnable对象,并不支持Callable。

/**
     * 这个方法有四个参数
     * @command::需要执行的任务
     * @initialDelay:第一次执行延迟
     * @period:执行周期
     * @TimeUnit:时间单位
     */
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit)
/**
 * 在执行器中周期性的执行任务
 *
 * 上一节我们学习了使用ScheduledThreadPoolExecutor来延迟执行任务,这一节我们需要学如何周期性地执行任务。
 *
 * 要想周期性的执行任务,我们需要调用scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS)方法。
 * 这个方法接受4个参数:
 *   第一个实现Runnable接口的任务实例
 *   第二个参数是第一次执行的延迟
 *   第三个参数是两次执行的时间间隔
 *   第四个参数是第二个参数和第三个参数的单位
 *
 * 这个方法返回一个ScheduledFuture<?>类型的对象,我们可以通过这个对象的getDelay()方法来返回任务到下一次执行时所需要等待的时间。
 *
 * ScheduledThreadPoolExecutor还提供了另外一个方法scheduleWithFixedDelay()。
 * 这个方法与scheduleAtFixedRate()方法接收的参数相同。
 * 只不过它的第三个参数不是两次执行开始的间隔时间,而是上一次任务执行结束到下次任务之行开始的间隔时间。
 *
 * Created by hadoop on 2016/11/3.
 */
public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(4);

        Task task = new Task("Task");

        ScheduledFuture<?> future = executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
        //ScheduledFuture<String> future = executor.scheduleWithFixedDelay(task, 1, 2, TimeUnit.SECONDS);

        for (int i =0; i < 10; i++) {
            System.out.printf("Main: Delay: %s. Result: %s\n", future.getDelay(TimeUnit.MILLISECONDS), future.get());

            TimeUnit.MILLISECONDS.sleep(1000);
        }

        executor.shutdown();

        executor.awaitTermination(1, TimeUnit.DAYS);
    }
}

我们每隔一秒钟打印一次,任务下次执行的时间间隔。其中有一点要说明的是,执行器给我们提供了两个周期任务执行方法。

  • scheduleAtFixedDelay():这个方法是从上一个任务执行开始就计算下次任务执行时间。
  • scheduleWithFixedDelay():这个方法是从上一个任务执行结束后才开始计算下次任务执行时间。

另外提一点,当设置执行器方法setContinueExistingPeriodicTasksAfterShutdownPolicy(true)为true的时候,即使关闭执行器,周期任务也会继续执行。

© 著作权归作者所有

阿拉德大陆的魔法师
粉丝 27
博文 91
码字总数 83019
作品 0
西城
程序员
私信 提问
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
733
1
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
684
1
Java多线程学习(八)线程池与Executor 框架

Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/JavaGuide 历史优质文章推荐: Java并发编程指南专栏 分布式系统的经典基础理...

snailclimb
2018/05/31
0
0
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
189
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

hanzhankang
2014/01/20
141
0

没有更多内容

加载失败,请刷新页面

加载更多

Replugin借助“UI进程”来快速释放Dex

public static boolean preload(PluginInfo pi) { if (pi == null) { return false; } // 借助“UI进程”来快速释放Dex(见PluginFastInstallProviderProxy的说明) return PluginFastInsta......

Gemini-Lin
今天
4
0
Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0
CSS--属性

一、溢出 当内容多,元素区域小的时候,就会产生溢出效果,默认是纵向溢出 横向溢出:在内容和容器之间再套一层容器,并且内部容器要比外部容器宽 属性:overflow/overflow-x/overflow-y 取值...

wytao1995
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
7
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部