文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java实现定时任务

2024-04-02 19:55

关注

本文实例为大家分享了Java实现定时任务的具体代码,供大家参考,具体内容如下

1 使用java.util.Timer

这种方式的定时任务主要用到两个类,Timer 和 TimerTask,使用起来比较简单。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。 TimerTask是一个抽象类,new的时候实现自己的 run 方法,然后将其丢给 Timer 去执行即可。

代码示例:

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

public class Schedule {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
            }
        };
        // 在指定延迟0毫秒后开始,随后地执行以2000毫秒间隔执行timerTask 
        new Timer().schedule(timerTask, 0L, 2000L);
        System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
    }
}

缺点:

2 使用ScheduledExecutorService

ScheduledExecutorService 即是 Timer 的替代者,JDK 1.5 并发包引入,是基于线程池设计的定时任务类。每个调度任务都会分配到线程池中的某一个线程去执行,任务就是并发调度执行的,任务之间互不影响。

Java 5.0引入了java.util.concurrent包,其中的并发实用程序之一是ScheduledThreadPoolExecutor ,它是一个线程池,用于以给定的速率或延迟重复执行任务。它实际上是Timer/TimerTask组合的更通用替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类TimerTask (只需实现Runnable)。使用一个线程配置ScheduledThreadPoolExecutor使其等效于Timer 。

代码示例:

import java.time.LocalDateTime;
import java.util.concurrent.*;

public class Schedule {
    public static void main(String[] args) {
        // 创建一个ScheduledThreadPoolExecutor线程池,核心线程数为5
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(5);
        // 创建Runnable打印当前线程和当前时间
        Runnable r = () -> System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
        
         // 在指定1秒延迟后执行r,之后每两秒执行一次
        scheduledExecutorService.scheduleAtFixedRate(r, 1, 2, TimeUnit.SECONDS);
    }
}

3 使用Spring Task

Spring Task 底层是基于 JDK 的 ScheduledThreadPoolExecutor 线程池来实现的。直接通过Spring 提供的 @Scheduled 注解即可定义定时任务,非常方便。

以Spring Boot来作为示例,步骤为

1.在启动类所在包下创建Schedule 类(在没有配置@ComponentScan的情况下,Spring Boot只会默认扫描启动类所在包的spring组件)
2.在该类上添加@Component和@EnableScheduling注解
3.在方法上添加@Scheduled注解,该注解主要参数如下

String cron() default "";  // 支持cron表达式

long fixedDelay() default -1;  // 在最后一次调用结束和下一次调用开始之间的时间间隔,以毫秒为单位
String fixedDelayString() default "";  // 同上,类似ScheduledExecutorService的scheduleWithFixedDelay

long fixedRate() default -1;  // 在调用之前的时间间隔,以毫秒为单位
String fixedRateString() default "";  // 同上,类似ScheduledExecutorService的scheduleAtFixedRate

long initialDelay() default -1;  // 在第一次执行fixedRate()或fixedDelay()任务之前要延迟的毫秒数
String initialDelayString() default "";  // 同上

代码示例:

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

import java.time.LocalDateTime;

@Component
@EnableScheduling
public class Schedule {
    @Scheduled(fixedRate = 2000L)
    public void task() {
        System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
    }
}

可以通过@EnableAsync和 @Async开启多线程

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

import java.time.LocalDateTime;

@Component
@EnableAsync  // 开启异步多线程
@EnableScheduling
public class Schedule {

    @Async
    @Scheduled(fixedRate = 2000L)
    public void task() {
        System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
    }
}

使用@EnableAsync注解后,默认情况下,Spring将搜索关联的线程池定义:上下文中的唯一org.springframework.core.task.TaskExecutor
的bean,或者名为“taskExecutor”的java.util.concurrent.Executor
的bean。如果两者都无法解析,则将使用org.springframework.core.task.SimpleAsyncTaskExecutor来处理异步方法调用。

TaskExecutor实现为每个任务启动一个新线程,异步执行它。 支持通过“concurrencyLimit”bean 属性限制并发线程。默认情况下,并发线程数是无限的,所以使用默认的线程池有导致内存溢出的风险。

注意:刚才的运行结果看起来是线程复用的,而实际上此实现不重用线程!应尽量实现一个线程池TaskExecutor ,特别是用于执行大量短期任务。不要使用默认的SimpleAsyncTaskExecutor。

import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.Executor;

@Component
@EnableAsync
@EnableScheduling
public class Schedule {

    @Async
    @Scheduled(fixedRate = 2000L)
    public void task() {
        System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
    }


    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(10);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("自定义-");
        taskExecutor.setAwaitTerminationSeconds(60);
        return taskExecutor;
    }
}

上面提到的一些定时任务的解决方案都是在单机下执行的,适用于比较简单的定时任务场景比如每天凌晨备份一次数据。如果我们需要一些高级特性比如支持任务在分布式场景下的分片和高可用的话,我们就需要用到分布式任务调度框架了,比如Quartz、Elastic-Job、XXL-JOB、PowerJob,本文就不再详细进行介绍了,感兴趣的可以自行查阅相关资料。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯