目录

ScheduledExecutorService 简述

对象创建方式

schedule + Runnable 延迟执行任务

schedule + Callable 延迟执行任务

scheduleAtFixedRate 周期性执行任务

scheduleWithFixedDelay 周期性执行任务


ScheduledExecutorService 简述

1、public interface ScheduledExecutorService extends ExecutorService 延迟或定期执行任务。

2、schedule 方法使用各种延迟创建任务,并返回一个可用于取消或检查执行的任务对象

3、scheduleAtFixedRate 和 scheduleWithFixedDelay 方法创建并执行某些在取消前一直定期运行的任务

4、所有的 schedule 方法都接受相对延迟和周期作为参数,而不是绝对的时间或日期

5、SheduleExecutorService 是JDK 1.5出来的,比以前的 Timer 性能好

Method  Description
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)

创建并执行在给定延迟后启用的单次操作。

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

创建并执行在给定延迟后启用的单次操作。

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

创建并执行在给定的初始延迟之后,以给定的时间间隔执行周期性动作。即在 initialDelay 初始延迟后,initialDelay+period 执行第一次,initialDelay + 2 * period  执行第二次,依次类推。

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

创建并执行在给定的初始延迟之后首先启用的定期动作,随后上一个执行的终止和下一个执行的开始之间给定的延迟。

对象创建方式

1、此实例最快捷的方式是使用 Executors 工具来创建:

ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行任务或者定期地执行任务。 corePoolSize - 池中所保存的线程数,即使线程是空闲的也包括在内。
ScheduledExecutorService newSingleThreadScheduledExecutor() 创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行任务。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。 同样这是一个无界的任务队列,即虽然线程只有一个,但是新增的任务会在队列中排队等待执行

2、此外除了使用 Executors 创建之外,推荐使用 ScheduledExecutorService 的实现类 ScheduledThreadPoolExecutor

schedule + Runnable 延迟执行任务

1、ScheduledFuture<?> schedule(Runnable command,long delay,TimeUnit unit) :创建并执行在给定延迟后启用的一次性操作。

2、参数:command - 要执行的任务;delay - 从现在开始延迟执行的时间;unit - 延迟参数的时间单位

import java.util.Date;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*** @author wangmaoxiong* Created by Administrator on 2018/6/28 0028.* 自定义任务*/
public class MyThread implements Runnable {private Random random = null;public MyThread() {random = new Random();}@Overridepublic void run() {try {System.out.println("任务执行开始:" + new Date());/**使用随机延时[0-3]秒来模拟执行任务*/int sleepNumber = random.nextInt(3);TimeUnit.SECONDS.sleep(sleepNumber);System.out.println("任务执行完毕:" + new Date());} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {/**使用Executors工具快速构建对象*/ScheduledExecutorService scheduledExecutorService =Executors.newScheduledThreadPool(1);System.out.println("3秒后开始执行计划线程池服务..." + new Date());scheduledExecutorService.schedule(new MyThread(), 3, TimeUnit.SECONDS);}
}

schedule + Callable 延迟执行任务

1、ScheduledFuture<V> schedule(Callable<V> callable, long delay,TimeUnit unit):创建并执行在给定延迟后启用的 一次性操作

2、参数:callable - 要执行的功能;delay - 从现在开始延迟执行的时间;unit - 延迟参数的时间单位

import java.util.Date;
import java.util.Random;
import java.util.concurrent.*;/*** Created by Administrator on 2018/6/28 0028.* @author wangmaoxiong*/
public class MyCall implements Callable {private Random random = null;public MyCall() {random = new Random();}@Overridepublic Object call() throws Exception {try {String threadName = Thread.currentThread().getName();System.out.println("任务执行开始:" + new Date() + ":" + threadName);/**使用随机延时[0-6]秒来模拟执行任务*/int sleepNumber = random.nextInt(6);TimeUnit.SECONDS.sleep(sleepNumber);System.out.println("任务执行完毕:" + new Date() + ":" + threadName);} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args) {/**使用Executors工具快速构建对象*/ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);System.out.println("3秒后开始执行计划线程池服务..." + new Date());Random random = new Random();/**计划任务线程池最大个数为2* 下面开启3个任务,则执行不过来的任务会排队等待执行*/for (int i = 0; i < 3; i++) {scheduledExecutorService.schedule(new MyCall(),random.nextInt(3), TimeUnit.SECONDS);}}
}

scheduleAtFixedRate 周期性执行任务

1、ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay, long period, TimeUnit unit):创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;

2、在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。意思是下一次执行任务的时间与任务执行过程花费的时间无关,只与period有关!

3、如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行。

4、如果任务的任何一个执行遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。

5、参数:command - 要执行的任务;initialDelay - 首次执行的延迟时间;period - 连续执行之间的周期;unit - initialDelay 和 period 参数的时间单位

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/*** Created by Administrator on 2018/6/28 0028.* 自定义任务*/
public class MyRunable implements Runnable {private AtomicInteger atomicInteger = null;private Random random = null;public MyRunable() {atomicInteger = new AtomicInteger(0);random = new Random();}@Overridepublic void run() {try {String threadName = Thread.currentThread().getName();System.out.println("1-任务执行开始:" + new Date() + ":" + threadName);/**使用随机延时[0-3]秒来模拟执行任务*/int sleepNumber = random.nextInt(5);TimeUnit.SECONDS.sleep(sleepNumber);if (atomicInteger.getAndAdd(1) == 3) {/** 故意抛出一个异常*/int error = 10 / 0;}System.out.println("2-任务执行完毕:" + new Date() + ":" + threadName);} catch (Exception e) {e.printStackTrace();}}
}

1)上面 run 方法中如果没有去捕获异常,即没有 try-catch 时,一旦抛出异常却没有捕获到,则后续的定时任务不会再继续执行,这就和 Timer 是一样的,可以参考《Java 定时器Timer与TimeTask》

2)try-catch 时一定要完全捕获到异常,例如果里面抛的是空指针异常,你捕获的却是数组下标越界异常,则仍然会中断计划任务,后续的任务仍然不再执行,所以建议:1)try-catch 包含 run 方法中的所有代码,2)catch 异常最外围使用 "Exception",以免某些异常未捕获而导致计划失败。

import java.util.Date;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*** Created by Administrator on 2018/6/28 0028.*/
public class Test {public static void main(String[] args) {/**使用Executors工具快速构建对象*/ScheduledExecutorService scheduledExecutorService =Executors.newSingleThreadScheduledExecutor();System.out.println("3秒后开始执行计划线程池服务..." + new Date());/**每间隔4秒执行一次任务*/scheduledExecutorService.scheduleAtFixedRate(new MyRunable(),3, 4, TimeUnit.SECONDS);}
}

scheduleWithFixedDelay 周期性执行任务

1、ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay,TimeUnit unit):创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。

2、与 scheduleFixedDelay 区别仅仅在于前后两次任务执行的时间间隔不同而已

import java.util.Date;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*** Created by Administrator on 2018/6/28 0028.*/
public class Test {public static void main(String[] args) {/**使用Executors工具快速构建对象*/ScheduledExecutorService scheduledExecutorService =Executors.newSingleThreadScheduledExecutor();System.out.println("3秒后开始执行计划线程池服务..." + new Date());/**每间隔4秒执行一次任务*/scheduledExecutorService.scheduleWithFixedDelay(new MyRunable(),3, 4, TimeUnit.SECONDS);}
}

在 scheduleFixedDelay 的例子上仅改变上面一行代码,运行结果如下

try-catch 时一定要完全捕获到异常,例如果里面抛的是空指针异常,你捕获的却是数组下标越界异常,则仍然会中断计划任务,后续的任务仍然不再执行,所以建议:1)try-catch 包含 run 方法中的所有代码,2)catch 异常最外围使用 "Exception",以免某些异常未捕获而导致计划失败。

ScheduledExecutorService 延迟 / 周期执行线程池相关推荐

  1. ScheduledExecutorService定时周期执行指定的任务

    一:简单说明 ScheduleExecutorService接口中有四个重要的方法,其中scheduleAtFixedRate和scheduleWithFixedDelay在实现定时程序时比较方便. ...

  2. ScheduledThreadPoolExecutor()定时执行线程池详解,java线程池

    为什么80%的码农都做不了架构师?>>>    package com.dy.pool;import java.util.concurrent.ExecutorService; im ...

  3. 小伙伴们,线程生命周期、线程池生命周期别再傻傻分不清楚了!!!

    文章目录 前言 线程的生命周期 线程池生命周期 CSDN独家福利降临!!! 尾言 前言 博主 常年游荡于牛客面经区,总结了字节.阿里.百度.腾讯.美团等等大厂的高频考题,之后会逐步分享给大家,期待各位 ...

  4. 《码农翻身》--知识点总结--01我是一个线程---线程生命周期、线程池、缓存、锁

    一.线程的生命周期 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态. 在线程的生命周期中,它要经过 新建(New).就绪(Runnable).运行(Running).阻 ...

  5. Java多线程系列 JUC线程池01 线程池框架

    转载  http://www.cnblogs.com/skywang12345/p/3509903.html 为什么引入Executor线程池框架 new Thread()的缺点 1. 每次new T ...

  6. 不会吧不会吧,不会有人连线程池都没听说过吧

    在上一篇文章中,我们介绍了创建线程的三种方法,但实际开发中如果需要频繁创建线程则不会使用前文说的那三种方法,而是选择使用线程池创建线程.使用线程池可以有效减少在手动创建线程过程中产生的开销,方便线程进 ...

  7. 为什么线程池里的方法会执行两次_别以为线程池很简单,来回答下这些问题!...

    前言 线程池可以说是 Java 进阶必备的知识点了,也是面试中必备的考点,可能不少人看了这篇文章后能对线程池工作原理说上一二,但这还远远不够,如果碰到比较有经验的面试官再继续追问,很可能会被吊打,考虑 ...

  8. redisson究极爽文-手把手带你实现redisson的发布订阅,消息队列,延迟队列(死信队列),(模仿)分布式线程池

    参考资料 :分布式中间件实战:java版 (书籍), 多线程视频教程(视频)- 项目启动环境 导入依赖 <parent><groupId>org.springframework ...

  9. 有赞一面:还有任务没执行,线程池被关闭怎么办?

    说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如极兔.有赞.希音的面试资格,遇到一几个很重要的面试题: 还有线程池正在执行的任务和线程,如果线程池shutd ...

  10. 如何判断线程池已经执行完所有任务了?

    作者 | 磊哥 来源 | Java面试真题解析(ID:aimianshi666) 转载请联系授权(微信ID:GG_Stone) 很多场景下,我们需要等待线程池的所有任务都执行完,然后再进行下一步操作. ...

最新文章

  1. PHP极其强大的图片处理库Grafika详细教程(3):图像属性处理
  2. 【转】一步一步学Linq to sql(五):存储过程
  3. 使用 ACE 库框架在 UNIX 中开发高性能并发应用
  4. 关于win10更新后谷歌浏览器打开卡慢或者无法上网的问题解决
  5. 方法练习2_求出1到100的累加和
  6. linux-Centos7安装python3并与python2共存
  7. LOJ#2132. 「NOI2015」荷马史诗
  8. 比较牛逼的答题卡扫描算法
  9. 《深度探索C++对象模型》调用虚函数
  10. Interview Experience in Singapore(Part Ⅲ)
  11. cookie,session与token的真正区别
  12. 3 个很酷的 Python 库,可以节省您的时间和精力
  13. [Spark机器学习]基于Spark 2.0 机器学习之推荐系统实现
  14. Ubuntu Tty (字符终端) 显示中文,和字体大小设置
  15. 第十二章:互联网-webbrowser:显示Web页面-使用特定浏览器
  16. 什么是SDN?用一篇文章彻底讲明白 SDN 软件定义网络是什么!
  17. 基于html的chm在线帮助设计与实现
  18. 国内邮箱免费邮箱注册哪个好?
  19. 华硕java安装教程win10_华硕骁龙835笔记本安装win10系统操作教程
  20. development enviroment

热门文章

  1. 引用计数指针实现(含源码)
  2. cass有坐标文件生成里程文件_【视频】南方cass9.0进阶教程74.3生成里程文件3
  3. python导入dat数据_收好Python代码,导入项目数据不费力
  4. 拓端tecdat|R语言分布滞后非线性模型(DLNM)空气污染研究温度对死亡率影响建模应用
  5. 拓端tecdat|R语言分段线性回归分析预测车辆的制动距离
  6. 拓端tecdat|R语言基于温度对城市层次聚类、kmean聚类、主成分分析和Voronoi图可视化
  7. 拓端tecdat|R语言中广义线性模型(GLM)中的分布和连接函数分析
  8. Linux下 <用户名> 不在 sudoers 文件中。此事将被报告。
  9. TCP/IP协议-三次握手四次挥手
  10. Scikit-learn快速入门教程和实例(一)(二)