ScheduledExecutorService 延迟 / 周期执行线程池

ScheduledExecutorService 延迟 / 周期执行线程池目录Executor结构图ScheduleExecutorService简述对象创建方式方法详解scheduleRunnablescheduleCallablescheduleAtFixedRatescheduleWithFixedDelay本文可参考《线程池理论2》Executor结构图ScheduleExecutorService…

大家好,又见面了,我是你们的朋友全栈君。

目录

ScheduledExecutorService 简述

对象创建方式

schedule + Runnable 延迟执行任务

schedule + Callable 延迟执行任务

scheduleAtFixedRate 周期性执行任务

scheduleWithFixedDelay 周期性执行任务


ScheduledExecutorService 延迟 / 周期执行线程池

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();
    }
    @Override
    public 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();
    }
    @Override
    public 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();
    }
    @Override
    public 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);
    }
}

ScheduledExecutorService 延迟 / 周期执行线程池

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 的例子上仅改变上面一行代码,运行结果如下

ScheduledExecutorService 延迟 / 周期执行线程池

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

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136955.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数学建模算法学习——各类模型算法汇总[通俗易懂]

    数学建模算法学习——各类模型算法汇总[通俗易懂]相关模型解决的问题数据分析类算法一览100个经典动态规划方程优化问题线性规划简介:线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号。为了避免这种形式多样性带来的不便,Matlab中规定线性规划的标准形式为其中c和x为n维列向量,A、Aeq为适当维数的矩阵,b、beq为适当维数的列向量。代码实现…

    2022年6月23日
    29
  • rst 网络_RST报文

    rst 网络_RST报文????现实很近又很冷,梦想很远却很温暖​欢迎关注CSDN:https://blog.csdn.net/ndrg55?spm=1011.2124.3001.5343&type=blog语雀:https://www.yuque.com/u12089348以下内容来源:https://mp.weixin.qq.com/s/Fr6o6gRiIUIspV9-jR9snw作者:小白debug注:内容有所改动一、什么是RST我们都知道TCP正常情况下断开连接是用四次挥手,那是正常时候的

    2022年9月28日
    3
  • 概率矩阵分解模型 PMF[通俗易懂]

    概率矩阵分解模型 PMF[通俗易懂]本文是论文《一种结合推荐对象间关联关系的社会化推荐算法》的笔记(上)。因为对其中的概率矩阵分解(ProbabilisticMatrixFactorization,PMF)不够了解,因而我先去脑补了PMF在推荐系统中的应用,然后再对论文进行总结。主要内容包括svd的两种形式和PMF的介绍。

    2022年6月18日
    61
  • c语言switch例题注释,switch语句例子大全 C语言switch语句例题

    c语言switch例题注释,switch语句例子大全 C语言switch语句例题CSS布局HTML小编今天和大家分享一个switch语句的例子matlab中switch语句的用法例子matlab中switch语句看了好几本教材上的例子都未看懂核心,不知谁能提供if-else-end语句所对应的是多重判断选择,而有时也会遇到多分支判断选择的问题。MATLAB语言为解决多分支判断选择提供了switch-case语句。switch-case语句的一般表达形式为:switch〈…

    2022年10月21日
    2
  • vue 引入js文件中的方法,在html中使用报错的问题「建议收藏」

    vue 引入js文件中的方法,在html中使用报错的问题「建议收藏」1.创建了一个common.js2.引入到vue文件中3.在html使用它4.发现报错5.解决报错,只需要在methods中声明一下它

    2022年10月8日
    2
  • totalcmd简单教程–help详解

    totalcmd简单教程–help详解configuartio 对话框中有个 tabstops 这表示每一栏的宽度 好像只对 Allfiledetai 按第三个 button 或对 tabstop 右键选 full 栏起作用 什么是 tabstop 对每一个 dialog 都可点 help 也可在 index 中输入 dialog 要想显示 comment 首先在 option display 中打开相应选项 最

    2025年7月24日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号