【小家java】Java定时任务ScheduledThreadPoolExecutor详解以及与Timer、TimerTask的区别(执行指定次数停止任务)(上)

简介: 【小家java】Java定时任务ScheduledThreadPoolExecutor详解以及与Timer、TimerTask的区别(执行指定次数停止任务)(上)

定时任务就是在指定时间执行程序,或周期性执行计划任务。Java中实现定时任务的方法有很多,本文从从JDK自带的一些方法来实现定时任务的需求。


Timer和TimerTask


本文先介绍Java最原始的解决方案:Timer和TimerTask


Timer和TimerTask可以作为线程实现的第三种方式,在JDK1.3的时候推出。但是自从JDK1.5之后不再推荐时间,而是使用ScheduledThreadPoolExecutor代替


public class Timer {}
// TimerTask 是个抽象类
public abstract class TimerTask implements Runnable {}


快速入门


Timer运行在后台,可以执行任务一次,或定期执行任务。TimerTask类继承了Runnable接口,因此具备多线程的能力。一个Timer可以调度任意多个TimerTask,所有任务都存储在一个队列中顺序执行,如果需要多个TimerTask并发执行,则需要创建两个多个Timer。


很显然,一个Timer定时器,是单线程的


public static void main(String[] args) throws ParseException {
        Timer timer = new Timer();
        //1、设定两秒后执行任务
        //timer.scheduleAtFixedRate(new MyTimerTask1(), 2000,1000);
        //2、设定任务在执行时间执行,本例设定时间13:57:00
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date time = dateFormatter.parse("2018/11/04 18:40:00");
        //让在指定的时刻执行(如果是过去时间会立马执行 如果是将来时间 那就等吧)
        timer.schedule(new MyTimerTask1(), time);
    }
    //被执行的任务必须继承TimerTask,并且实现run方法
    static class MyTimerTask1 extends TimerTask {
        public void run() {
            System.out.println("爆炸!!!");
        }
    }


相关API简单介绍(毕竟已经不重要了):

schedule(TimerTask task, long delay, long period) --指定任务执行延迟时间

schedule(TimerTask task, Date time, long period) --指定任务执行时刻

scheduleAtFixedRate(TimerTask task, long delay, long period)

scheduleAtFixedRate(TimerTask task, Date firstTime, long period)


这里需要注意区别:


   schedule:


   scheduleAtFixedRate:


相关文章度娘一下,可找到答案。因此本文不做介绍了,毕竟不是本文重点。


终止Timer线程


调用Timer.cancle()方法。可以在程序任何地方调用,甚至在TimerTask中的run方法中调用;

设置Timer对象为null,其会自动终止;

用System.exit方法,整个程序终止。


下面例子:

启动一个timer任务,执行指定次数/时间后停止任务


备注:该示例在某些特殊的场景会很有用的,比如守护监控、守护检查等等


/**
 * 定时器
 *
 * @author fangshixiang
 * @description //
 * @date 2019/1/22 17:55
 */
public class TaskTest {
    /**
     * 需求描述:满足条件后启动一个定时任务,再满足另外一个条件后停止此定时任务
     * (阶段性定时任务)
     * 备注:若单线程就能搞定,就使用timer即可,若需要多线程环境,请使用JDK5提供的ScheduledThreadPoolExecutor
     */
    public static void main(String[] args) {
        Timer timer = new Timer();
        // 三秒后开始执行任务,每隔2秒执行一次  当执行的总次数达到10此时,停止执行
        timer.schedule(new Task(timer, 10), 3 * 1000, 2000);
    }
}
class Task extends TimerTask {
    private Timer timer;
    private int exeCount; //此处没有线程安全问题
    public Task(Timer timer, int exeCount) {
        this.timer = timer;
        this.exeCount = exeCount;
    }
    private int i = 1;
    @Override
    public void run() {
        System.out.println("第" + i++ + "次执行任务");
        //处理业务逻辑start...
        //处理业务逻辑end...
        //若满足此条件 退出此线程
        if (i > exeCount) {
            this.timer.cancel();
            System.out.println("#### timer任务程序结束 ####");
        }
    }
}


输出:


第1次执行任务
第2次执行任务
第3次执行任务
第4次执行任务
第5次执行任务
第6次执行任务
第7次执行任务
第8次执行任务
第9次执行任务
第10次执行任务
#### timer任务程序结束 ####



相关文章
|
25天前
|
数据采集 缓存 Java
Python vs Java:爬虫任务中的效率比较
Python vs Java:爬虫任务中的效率比较
|
3天前
|
NoSQL Java 调度
Java调度任务如何保证相同任务在一个周期里只执行一次?
【10月更文挑战第29天】Java调度任务如何保证相同任务在一个周期里只执行一次?
21 6
|
3天前
|
存储 NoSQL Java
Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?
【10月更文挑战第29天】Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?
13 1
|
1月前
|
Java
用java搞定时任务,将hashmap里面的值存到文件里面去
本文介绍了如何使用Java的`Timer`和`TimerTask`类创建一个定时任务,将HashMap中的键值对写入到文本文件中,并提供了完整的示例代码。
34 1
用java搞定时任务,将hashmap里面的值存到文件里面去
|
19天前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
105 1
|
29天前
|
Java Shell Maven
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
89 4
|
2月前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
38 5
消息中间件 缓存 监控
105 0
|
7天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
1天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####