JAVA实现定时任务

本文总结了三种JAVA实现定时任务的方法:线程、Timer和SpringBoot注解开发。通过实例代码详细介绍了每种方式的使用,并提供了代码下载链接,旨在帮助开发者处理定时更新数据、清理缓存等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要

我们在项目中经常会处理一些定时更新的数据,比如定期删除缓存的token,设置订单的有效时间,利用定时任务处理日志及一些缓存,或者定期做更新数据等一系列的复杂业务;在这里我做了一份总结,希望能帮到大家;如果有不准确的地方希望能够提供宝贵的建议
代码下载地址:https://github.com/tazhigang/TimedTask.git

1、线程实现定时任务

话不多说,直接上代码

package com.ittzg.task;

/**
 * @Author: ittzg
 * @CreateDate: 2018/12/7
 * @Description: 线程实现定时任务
 * 运行环境是JDK8 使用lambda表达式 大家可以下去看看
 */
public class TimedTaskDemo01 {
    public static void main(String[] args) {
        new Thread(() ->{ 
            int time = 1;
            while(true){
                //每5秒钟执行一次
                
                System.out.println("Perform the task every 5 secouds!\t"+(time++)+"\t"+new Date());
                try {Thread.sleep(5000);} catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

运行结果

	Perform the task every 5 secouds!	1	Fri Dec 07 14:59:08 GMT+08:00 2018
	Perform the task every 5 secouds!	2	Fri Dec 07 14:59:13 GMT+08:00 2018
	Perform the task every 5 secouds!	3	Fri Dec 07 14:59:18 GMT+08:00 2018
	......

2、Timer实现定时任务

package com.ittzg.task;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @Author: ittzg
 * @CreateDate: 2018/12/7 13:17
 * @Description: 使用Timer完成定时任务
 */
public class TimedTaskDemo02 {
    public static void main(String[] args) throws ParseException {
        System.out.println("程序执行时间"+new Date());
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("this is a timerTask /n 目标任务执行时间:"+new Date());
            }
        };
        Timer timer = new Timer();
        /*//1.schedule(TimerTask task, Date time) 表示在指定的时间点执行task
        Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2018-12-07 13:57:50");

        timer.schedule(timerTask,date);*/
       /* //2.schedule(TimerTask task, long delay) 表示延迟delay毫秒以后执行task
        timer.schedule(timerTask,5000); //5000表示5秒*/

        /*//3.schedule(TimerTask task, Date firstTime, long period) 表示任务从date时候
        //首次开始执行,以后每period 毫秒执行一次
        Date date1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2018-12-07 14:18:30");
        timer.schedule(timerTask,date1,5000);*/

        //4.schedule(TimerTask task, long delay, long period)
        // 表示任务从delay毫秒时候开始首次执行,以后每period 毫秒执行一次
        timer.schedule(timerTask,5000,5000);

        //5.scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
        // 表示任务从date时候首次开始执行,以后每period 毫秒执行一次

        //6.scheduleAtFixedRate(TimerTask task, long delay, long period)
        // 表示任务从delay毫秒时候开始首次执行,以后每period 毫秒执行一次
    }
}
	......

以上方法是用白话描述的,方便大家理解

这里说明一下
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)与
schedule(TimerTask task, Date firstTime, long period)的功能看起来一样但是却有所不同
我们来参考API说明一下
	1. schedule方法在api中给出了如下解释
		In fixed-delay execution, each execution is scheduled relative to the actual 
	execution time of the previous execution. If an execution is delayed for any 
	reason (such as garbage collection or other background activity), subsequent 
	executions will be delayed as well. In the long run, the frequency of execution 
	will generally be slightly lower than the reciprocal of the specified period 
	(assuming the system clock underlying Object.wait(long) is accurate). As a 
	consequence of the above, if the scheduled first time is in the past, it is 
	scheduled for immediate execution.
	大致的意思是:在固定的延迟执行中,每一次执行都是在初次执行的基础上,按照预定时间对任务
		进行调度,如果由于任何原因所导致的执行延迟(比如垃圾回收,后台干扰运行),
		则后续执行的任务也将延迟;从长远来看,执行频率通常会略低于指定时间段的
		倒数。除此之外,如果计划的第一时间是过去的,则计划立即执行。
	2.scheduleAtFixedRate方法在api中给出了如下解释
		In fixed-rate execution, each execution is scheduled relative to the scheduled 
	execution time of the initial execution. If an execution is delayed for any reason 
	(such as garbage collection or other background activity), two or more executions 
	will occur in rapid succession to "catch up." In the long run, the frequency of 
	execution will be exactly the reciprocal of the specified period (assuming the 
	system clock underlying Object.wait(long) is accurate).
	大致的意思是:在固定的延迟执行中,每一次执行都是在初次执行的基础上,按照预定时间对任务
		进行调度,如果由于任何原因所导致的执行延迟(比如垃圾回收,后台干扰运行),
		则scheduleAtFixedRate方法将快速连续地出现两次或更多的执行,从而使后续执行能
		够“追赶上来”。从长远看,执行的频率很接近指定的周期。

3、SpringBoot实现定时任务(注解开发)

1.创建springboot的maven项目
1> 项目包结构
在这里插入图片描述
2>pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
	 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.ittzg</groupId>
	<artifactId>schema</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>schema</name>
	<description>this is timedTask</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

2.定时任务类

package com.ittzg.task;

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

import java.util.Date;

/**
 * @Author: ittzg
 * @CreateDate: 2018/12/7 20:55
 * @Description:
 */
@Component  //一定要加,否则启动时不会创建该类,更扫描不到定时任务
public class TimedTaskDemo {
    //cron生成器地址 http://cron.qqe2.com/
        // 注意生成的cron 在运行时会出现
        //Cron expression must consist of 6 fields (found 7 in "0 * * * * ? *")
        // 这时候果断把最后一位去掉
    @Scheduled(cron = "0/5 * * * * ?") 
    public void printMsg(){
        //此处写你的业务代码
        System.out.println("这是一个定时任务\t" +new Date());
    }
}

3.启动类

package com.ittzg;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling //启动类一定不要忘记加这个注解,否则定时任务不会触发
public class SchemaApplication {

	//如果不在TimedTaskDemo上加@Component,可以使用以下代码代替该注解
	/*@Bean 
	public TimedTaskDemo getBean(){
		return new TimedTaskDemo();
	}*/

	public static void main(String[] args) {
		SpringApplication.run(SchemaApplication.class, args);
	}
}

4.运行启动类结果

这是一个定时任务	Fri Dec 07 21:29:25 GMT+08:00 2018
这是一个定时任务	Fri Dec 07 21:29:30 GMT+08:00 2018
这是一个定时任务	Fri Dec 07 21:29:35 GMT+08:00 2018
这是一个定时任务	Fri Dec 07 21:29:40 GMT+08:00 2018
这是一个定时任务	Fri Dec 07 21:29:45 GMT+08:00 2018
......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值