三种常用的java定时器

今天在公司做事突然发现定时器没跑,原来自己少做了东西。。。

记录一下自己学习过的几种定时器,我就用springboot示范一下

1.@Scheduled

package com.example.test;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class Test {
    // 每10秒执行一次
    @Scheduled(cron = "0/10 * * * * ?")
    public void executeFileDownLoadTask() {
        System.out.println("每10秒执行一次");
    }
}
image

2.quartz

Quartz任务调度的核心元素为:Scheduler——任务调度器、Trigger——触发器、Job——任务。其中trigger和job是任务调度的元数据,scheduler是实际执行调度的控制器。

  Trigger是用于定义调度时间的元素,即按照什么时间规则去执行任务。Quartz中主要提供了四种类型的trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,和NthIncludedDayTrigger。这四种trigger可以满足企业应用中的绝大部分需求。

  Job用于表示被调度的任务。主要有两种类型的job:无状态的(stateless)和有状态的(stateful)。对于同一个trigger来说,有状态的job不能被并行执行,只有上一次触发的任务被执行完之后,才能触发下一次执行。Job主要有两种属性:volatility和durability,其中volatility表示任务是否被持久化到数据库存储,而durability表示在没有trigger关联的时候任务是否被保留。两者都是在值为true的时候任务被持久化或保留。一个job可以被多个trigger关联,但是一个trigger只能关联一个job。

  Scheduler由scheduler工厂创建:DirectSchedulerFactory或者StdSchedulerFactory。第二种工厂StdSchedulerFactory使用较多,因为DirectSchedulerFactory使用起来不够方便,需要作许多详细的手工编码设置。Scheduler主要有三种:RemoteMBeanScheduler,RemoteScheduler和StdScheduler。

首先我们要引入依赖,如果不写版本号,spring-boot-starter-parenth会为我们提供常用jar包版本,自己指定版本号也可以,会覆盖官方版本

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

我们先创建一个类,类中有两个方法,一个是重写的方法,一个是普通的方法

package com.example.test;

import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

@Component(value = "test1")
public class Test extends QuartzJobBean {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        System.out.println("Test 当前时间为:" + LocalDateTime.now() + ", 屌丝" + name + "已经" + age + "岁了");
    }

    public void test() {
        System.out.println("Test1 当前时间是:" + LocalDateTime.now());
    }

}

然后我们创建定时器的配置类,@Configuration注明类是配置类,@Bean是将方法提交容器启动管理

package com.example.test;

import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.SimpleTrigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.*;

@Configuration
public class QuratzConfig {

    //Job  编辑任务
    @Bean
    JobDetailFactoryBean job() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(Test.class);//类要继承QuartzJobBean
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("name", "张三");//填充参数,字段名要对应,可不填
        jobDataMap.put("age", "25");//填充参数,字段名要对应,可不填
        bean.setJobDataMap(jobDataMap);
        bean.setDurability(true);
        return bean;
    }

    //Job  编辑任务
    @Bean
    MethodInvokingJobDetailFactoryBean job1() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("test1");//类的bean名称
        bean.setTargetMethod("test");//不能使用重写的方法
        return bean;
    }

    //Trigger  创建定时器
    @Bean
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setJobDetail(job().getObject());//可以对应不同的Job,一个job可以被多个trigger关联,但是一个trigger只能关联一个job
        bean.setRepeatCount(5);//设置循环次数,实际运行六次
        bean.setStartDelay(2000);//设置任务启动延迟时间,就是设置多久后开始第一次运行方法
        bean.setRepeatInterval(5000);//设置任务的时间间隔
        return bean;
    }

    //Trigger  创建定时器
    @Bean
    CronTriggerFactoryBean cronTriggerFactoryBean() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setJobDetail(job1().getObject());//可以对应不同的Job,一个job可以被多个trigger关联,但是一个trigger只能关联一个job
        bean.setCronExpression("* * * * * ?");//corn表达式,每5秒执行一次
        return bean;
    }

    //Scheduler  加载定时器
    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        SimpleTrigger simpleTrigger = simpleTriggerFactoryBean().getObject();
        CronTrigger cronTrigger = cronTriggerFactoryBean().getObject();
        bean.setTriggers(simpleTrigger, cronTrigger);
        return bean;
    }

}
image

3.Timer

使用Timer的schedule,schedule有3个参数:
schedule(TimerTask task, long delay, long period)
第一个为定时任务,根据业务需要重写TimerTask的run方法即可;
第二个为延时启动,就是设置多久后开始第一次运行方法,单位毫秒;
第三个位多久运行一次,单位毫秒;
首先我们先创建一个类,继承TimerTask,重写run方法

package com.example.test;

import java.time.LocalDateTime;
import java.util.TimerTask;

public class Test extends TimerTask {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Test(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public void run() {
        System.out.println("当前时间:" + LocalDateTime.now() + ", 屌丝" + name + "已经" + age + "岁了");
    }
}

然后我们创建定时器的配置类,@Configuration注明类是配置类,@Bean是将方法提交容器启动管理

package com.example.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Timer;

@Configuration
public class MyTimer {
    @Bean
    public void ceshi() {
        Timer timer = new Timer();
        Test test = new Test("张三", 25);
        timer.schedule(test, 2000L, 1000L);
    }
}
image

网上还有一种是通过线程实现的,主要是依靠线程休眠处理,这里我就不说了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349