封装系统如何做自己的网站,专做英文类网站,姑苏美食标题网页设计素材,域名和WordPress1、java自带的Timer
Timer是java中自带的类。 优点#xff1a;使用简单#xff0c;缺点是当添加并执行多个任务时#xff0c;前面任务的执行用时和异常将影响到后面任务。
Timer timer new Timer();timer.schedule(new TimerTask() {int i 0;Overridepublic void run() …1、java自带的Timer
Timer是java中自带的类。 优点使用简单缺点是当添加并执行多个任务时前面任务的执行用时和异常将影响到后面任务。
Timer timer new Timer();timer.schedule(new TimerTask() {int i 0;Overridepublic void run() {System.out.println(循环执行的代码块 i);}},启动后多长时间按第一次开始执行,间隔执行时间);讲解源码讲解
2、ScheduledThreadPool-定时任务线程池
ScheduledExecutorService 也是Java自带的类它可以实现Timer具备的所有功能并解决了 Timer类存在的问题。 优点该类是JDK1.5自带的类使用简单缺点是该方案仅适用于单机环境。
ScheduledExecutorService scheduledThreadPool Executors.newScheduledThreadPool(该线程池里的线程数);scheduledThreadPool.scheduleAtFixedRate(new Runnable() { public void run() {System.out.println(循环代码块);}},初始延迟,迟期, 时间单位);
参数1、任务主体循环代码块
2、首次执行的延时时间
3、任务执行间隔
4、间隔时间单位讲解源码讲解
3、Spring Task
Spring系列框架中Spring Framework自带的定时任务可以实现某些特定需求比如每周一执行某任务。 1、开启定时任务在SpringBoot的启动类上声明 EnableScheduling
SpringBootApplication
EnableScheduling //开启定时任务
public class SystemApplication { // -- --
}2、添加定时任务只需使用Scheduled注解标注即可如果有多个定时任务可以创建多个Scheduled标注的方法。Spring Boot 启动后会自动加载并执行定时任务无需手动操作。
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
Component // 把此类托管给 Spring
public class TaskUtils { // 添加定时任务 Scheduled(cron 30 00 10 0 0 5) // cron表达式每周一 10:00:30 执行 public void doTask(){ System.out.println(我是定时任务~); }
}4、分布式定时任务
分布式环境可以使用 Redis 来实现定时任务。 使用 Redis 实现延迟任务的方法大体可分为两类通过 ZSet 的方式和键空间通知的方式。
ZSet 实现方式
通过 ZSet 实现定时任务的思路是将定时任务存放到 ZSet 集合中并且将过期时间存储到 ZSet 的 Score 字段中然后通过一个无线循环来判断当前时间内是否有需要执行的定时任务如果有则进行执行。
import redis.clients.jedis.Jedis;
import utils.JedisUtils;
import java.time.Instant;
import java.util.Set;
public class DelayQueueExample { private static final String _KEY DelayQueueExample; public static void main(String[] args) throws InterruptedException { Jedis jedis JedisUtils.getJedis(); // 30s 后执行 long delayTime Instant.now().plusSeconds(30).getEpochSecond(); jedis.zadd(_KEY, delayTime, order_1); // 继续添加测试数据 jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), order_2); jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), order_3); jedis.zadd(_KEY, Instant.now().plusSeconds(7).getEpochSecond(), order_4); jedis.zadd(_KEY, Instant.now().plusSeconds(10).getEpochSecond(), order_5); // 开启定时任务队列 doDelayQueue(jedis); } /** * 定时任务队列消费 * param jedis Redis 客户端 */ public static void doDelayQueue(Jedis jedis) throws InterruptedException { while (true) { // 当前时间 Instant nowInstant Instant.now(); long lastSecond nowInstant.plusSeconds(-1).getEpochSecond(); // 上一秒时间 long nowSecond nowInstant.getEpochSecond(); // 查询当前时间的所有任务 Set data jedis.zrangeByScore(_KEY, lastSecond, nowSecond); for (String item : data) { // 消费任务 System.out.println(消费 item); } // 删除已经执行的任务 jedis.zremrangeByScore(_KEY, lastSecond, nowSecond); Thread.sleep(1000); // 每秒查询一次 } }
}键空间通知
可以通过 Redis 的键空间通知来实现定时任务它的实现思路是给所有的定时任务设置一个过期时间等到了过期之后我们通过订阅过期消息就能感知到定时任务需要被执行了此时我们执行定时任务即可。 默认情况下 Redis 是不开启键空间通知的需要我们通过 config set notify-keyspace-events Ex 的命令手动开启。
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import utils.JedisUtils;
public class TaskExample { public static final String _TOPIC __keyevent0__:expired; // 订阅频道名称 public static void main(String[] args) { Jedis jedis JedisUtils.getJedis(); // 执行定时任务 doTask(jedis); } /** * 订阅过期消息执行定时任务 * param jedis Redis 客户端 */ public static void doTask(Jedis jedis) { // 订阅过期消息 jedis.psubscribe(new JedisPubSub() { Override public void onPMessage(String pattern, String channel, String message) { // 接收到消息执行定时任务 System.out.println(收到消息 message); } }, _TOPIC); }
}SpringBoot中使用Redis实现分布式锁
5、springboot整合xxl-job实现定时任务
注后续继续补充