Java 实现定时器ScheduledThreadPoolExecutor

延迟任务:在100秒后执行该任务

周期任务:每10秒执行一次任务

Timer存在一些缺陷,应该考虑使用ScheduleThreadPoolExecutor 来代替他。

可以通过ScheduleThreadPoolExecutor 的构造函数或Executors 的 newScheduleThreadPool  工厂方法来创建该类的对象。

Timer在执行所有定时任务时只会创建一个线程。如果某个任务执行时间过长,那么将破坏其他TimerTask的定时精确性。

Timer另一个问题是如果TimeTask抛出了一个未检查的异常,那么Timer将表现出槽糕的行为。Timer线程并不捕获异常,因此

当TimerTask抛出未检查的异常时将终止定时线程。这种情况下,Timer也不会恢复线程的执行,而是会错误地认为整个Timer都消失了。

因此,已经被调度但尚未执行的TimerTask将不会再执行,新的任务也不会被调度。这就是线程泄漏。

ScheduledThreadPoolExecutor继承结构

延迟和周期任务的执行

如下代码片段

package com.usoft.schedule;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author: Lenovo(2015-08-13 23:54)
 */
public class ScheduledTest {

    public static void main(String args[]) throws ExecutionException, InterruptedException {
        ScheduledExecutorService schedule = Executors
                .newScheduledThreadPool(2);

        /**
         * 延迟1秒执行任务一次
         */
        schedule.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world runnable");
            }
        }, 1000, TimeUnit.MILLISECONDS);

        /**
         * 延迟2秒执行任务一次
         */
        Future result = schedule.schedule(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world callable";
            }
        }, 2000, TimeUnit.MILLISECONDS);

        System.out.println(result.get());

        // 以固定的频率来周期的执行任务
        schedule.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("定时周期任务执行");
            }
        }, 1000, 2000, TimeUnit.MILLISECONDS);

        // 以固定的延迟来周期的执行任务
        schedule.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                System.out.println("定时周期任务执行");
            }
        }, 1000, 3000, TimeUnit.MILLISECONDS);

        // 关闭定时和周期任务的执行
        Thread.sleep(1000 * 10);
        schedule.shutdown();
        System.out.println("pool shutdown:" + schedule.isShutdown());
        while (!schedule.isTerminated()) {
            schedule.awaitTermination(1, TimeUnit.SECONDS);
        }
    }
}

定时任务的执行

要说定时任务,其实都是用延迟任务和周期任务来实现定时的。

比如说,我要在每天的中午12点启动一个定时任务,就要根据当前程序的启动时间来算出延迟多长时间来执行这个任务,并且是周期的执行,有一个固定的算法来算出延迟的时长。

package com.usoft.schedule;

import java.util.Calendar;

public class Main23 {

    private static final int period = 1000 * 60; //秒
    private static final int one_day_millseconds = 24 * 60 * 60 * 1000;

    public static void main(String args[]) {
        int dayOfHour = 0; // 24h 制
        int minute = 0;
        int second = 0;
        long delay;  //首次执行任务的延迟
        Calendar c = Calendar.getInstance();
        long currentTime = c.getTimeInMillis();
        c.set(Calendar.HOUR_OF_DAY, dayOfHour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, second);
        long executeTime = c.getTimeInMillis();
        delay = executeTime - currentTime < 0 ? (executeTime - currentTime + one_day_millseconds)
            : (executeTime - currentTime);
        System.out.println("DelayTimeInMillis =" + delay);
        System.out.println("DelayTimeInSecond =" + delay / 1000);
        System.out.println("DelayTimeInHour =" + delay / (1000 * 60 * 60));
    }
}

这里简单的指定小时分钟和秒,也就说当到了这个时刻就要周期的执行这个任务。那么要延迟多长时间执行这个任务就可以根据以上代码来算出来。

也可以选择不是周期的执行任务,只是在这个时刻执行一次任务。

====================END====================

时间: 2024-12-18 12:36:19

Java 实现定时器ScheduledThreadPoolExecutor的相关文章

使用Java写定时器

Java编写处理定时任务主要用到的类是java.util.Timer和java.util.TimerTask: 如下几行代码就可以实现一个具有定时执行任务的定时器: import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import MailSender.MailSe

java中定时器的应用实例

1 package com.xiangshang.listener; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 import javax.servlet.ServletContextEvent; 7 import javax.servlet.ServletContextListener; 8 9 public class MyTimerListener implements ServletContextListen

java Quartz定时器任务与Spring task定时的几种实现,

java Quartz定时器任务与Spring task定时的几种实现 基于java 的定时任务实现, Quartz 时间详细配置    请查阅   http://www.cnblogs.com/sihuanian/p/5010872.html Quartz 时间简单介绍    请查阅最底部 spring框架来介绍. 一.分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask

JAVA Timer定时器使用方法

JAVA  Timer 定时器测试 MyTask.java:package com.timer; import java.text.SimpleDateFormat;import java.util.Date;import java.util.TimerTask; public class MyTask extends TimerTask{        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

java之定时器任务Timer用法

在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. public void schedule(TimerTask task,Date time) 这个方法中如启动时,已经过了time的时间,则系统会在启动后直接执行一次, 话不多少直接上代码 package com.test.timer.task; import java.text.DateFormat;

java Timer定时器管理类

1.java timer类,定时器类.启动执行定时任务方法是timer.schedule(new RemindTask(), seconds*1000);俩参数分别是TimerTask子类,具体执行定时操作所执行的动作,后一个参数是豪秒,代表间隔多久执行一次.2.TimerTask类,java.util.TimerTask,具体定时执行的操作.里面有个run方法,和线程run方法一样(就是线程).5.Timer是一种定时器工具,用来在一个后台线程计划执行指定任务.它可以计划执行一个任务一次或反复

java的定时器用法

java定时器的使用 定时器类Timer在java.util包中.使用时,先实例化,然后使用实例的schedule(TimerTask task, long delay)方法,设定指定的任务task在指定的延迟delay后运行.定时器任务类TimerTask是抽象类,继承并重写其run()方法,可实现详细任务. schedule(TimerTask task, Date time)设定指定任务task在指定时间time运行. cancel()方法结束这个定时器. schedule(TimerTa

Java 实现定时器Timer

1. Timer和TimerTask Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任务. 2. 一个Timer调度的例子 实现Task package com.usoft.timer; import java.util.TimerTask; public class Task extends TimerTask {

Java EE 定时器

写一个定时任务类,继承java.tuil.TimerTask,重写run()方法,在该方法中实现任务业务代码. package com.gao.timertask; import java.util.TimerTask; public class MyTimerTask extends TimerTask {     public MyTimerTask() {}          @Override     public void run() {         //定时任务业务逻辑代码