定时任务的使用以及学习

在前一实现数据的抓取:OkHttp3中,获得了想要的数据。但是 ,由于目标数据是实时更新的,所以需要实时获取。
本文介绍了四种定时任务:TimerScheduledExecutorServiceSpring TaskQuartz

一、Timer

  • 博文链接:定时器Timer
  • 同样的,自己测试了一个简单的demo
public class Test {

    public static void main(String[] args) throws ParseException {
        final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, 3000,3000);
    }
}

安装了 Alibaba Java Coding Guidelines 的插件之后,他会报出预警:
在这里插入图片描述

二、 ScheduledExecutorService

定时任务和线程池功能结合,能够更好的处理java中的一些并发的任务需要。
两种最常用的调度方法

  • ScheduleAtFixedRate
  • ScheduleWithFixedDelay

1. 创建任务

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @apiNote
 * @date: 2021/9/16 16:15
 */
public class MyScheduledExecutor implements Runnable {

    public void run() {
        //创建时间格式,精确到毫秒
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
        //打印开始执行的系统时间
        System.out.println(sdf.format(new Date()));
        //执行任务的主要部分,打印100w个空字符串,耗时比较长
        for (int i = 0; i < 100000000; i++) {
            System.out.print("");
        }
        //打印结束执行的系统时间
        System.out.println(sdf.format(new Date()));
        //与下次执行的结果分割开
        System.out.println("=============================");
    }
}

2. 执行scheduleAtFixedRate()方法

按照固定的节奏安排任务


import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author hanyulin
 * @apiNote
 * @date: 2021/9/9 16:21
 */

public class Test {

    public static void main(String[] args) {
    
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        // 延迟10之后的任务开始执行
        long initialDelay = 10;

        // 连续执行任务之间的时间:20
        // 即:上一次开始的时间与下一次开始的时间的间隔
        // 如果任务执行一次的时间超过了period,下次任务会紧随上次任务的结束而开始执行。
        long period = 20;
        
        service.scheduleAtFixedRate(new MyScheduledExecutor(), initialDelay, period, TimeUnit.SECONDS);

       
//        service.scheduleWithFixedDelay(new MyScheduledExecutor(), initialDelay, period, TimeUnit.SECONDS);

    }
}

控制台打印的结果如下:


2021-09-16 17:17:05:782
2021-09-16 17:17:14:300
=============================
2021-09-16 17:17:25:670
2021-09-16 17:17:34:442
=============================
2021-09-16 17:17:45:669
2021-09-16 17:17:54:513
=============================
2021-09-16 17:18:05:671
2021-09-16 17:18:14:525
=============================
2021-09-16 17:18:25:672

就类似于,老板指派了你明天(initialDelay = 1天 )的任务:定时每天(period = 1天)去安装硬件。第二天到了,你就开始干活。

  • 情景一:如果你干的快,3小时干完了,那么,今天得其他小时你就可以摸鱼了,等到第二天任务开始,你就又开始工作。
  • 情景二:要是任务其实得两天才能够把预计1天的硬件安装完成,远大于预估期(period = 1天)。那么你就会休息都不休息,做完了还得做(即:下次任务会紧随上次任务的结束而开始执行)。如下图:

在这里插入图片描述

3. 执行scheduleWithFixedDelay方法

    public static void main(String[] args) {

        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        // 延迟10之后的任务开始执行
        long initialDelay = 10;

        // 连续执行任务之间的时间:20 即:上一次结束的时间与下一次开始的时间的间隔
        // 如果任务执行一次的时间超过了period,下次任务在上次任务的结束时间后的20而开始执行。
        long period = 20;
        service.scheduleWithFixedDelay(new MyScheduledExecutor(), initialDelay, period, TimeUnit.SECONDS);

    }

控制台打印的结果如下:

2021-09-16 17:40:05:105
2021-09-16 17:40:13:257
=============================
2021-09-16 17:40:33:265
2021-09-16 17:40:41:610
=============================
2021-09-16 17:41:01:618
2021-09-16 17:41:10:520
=============================
2021-09-16 17:41:30:524
2021-09-16 17:41:39:246
=============================
2021-09-16 17:41:59:255
2021-09-16 17:42:08:54

就类似于,老板指派了你明天(initialDelay = 1天 )的任务:不管做完的时间长短,做完之后定时休息了(period = 1天)再去安装硬件。

三、Spring Task

1. yml文件配置Redis

  1. 把实时抓取到的数据放到Redis里面进行实时更新
  2. 这样在执行这个请求的时候,就能够保证数据的时效性
spring:
  redis:
    host: 127.0.0.1  # redis地址
    port: 6379  # redis端口号
    database: 0
    lettuce:
      pool:
        min-idle: 1
        max-active: 3
        max-idle: 2
        max-wait: -1ms
        time-between-eviction-runs: 100000

2. 启动类上添加注解@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class TestApplication {

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

}

3. 创建任务

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.weixin.login.FilDTO;
import com.weixin.login.util.OkHttp3Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author helen
 * @apiNote
 * @date: 2021/9/10 15:09
 */
@Component
public class FilJob {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Scheduled(cron = "*/5 * * * * ?")
    // cron表达式 http://qqe2.com/cron/index
    public void filJob() {
        String result = OkHttp3Util.send("https://api.filscout.com/api/v1/network/overview/info", null, OkHttp3Util.GET, null);
        if (result != null) {
            Map map = JSONUtil.toBean(result, Map.class);
            JSONObject data = (JSONObject) map.get("data");
            Map<String, Object> linkedTreeMap = JSONUtil.toBean(data, Map.class);
            FilDTO filDTO = new FilDTO();
            filDTO.setActiveMiners((Integer) linkedTreeMap.get("activeMiners"));
            filDTO.setBlockRewardIn24h((BigDecimal) linkedTreeMap.get("blockRewardIn24h"));
            filDTO.setNewlyFilIn24h((BigDecimal) linkedTreeMap.get("newlyFilIn24h"));
            filDTO.setOneDayMessages((Integer) linkedTreeMap.get("oneDayMessages"));
            filDTO.setPowerIn24H((String) linkedTreeMap.get("PowerIn24H"));
            filDTO.setTransferIn24H((Integer) linkedTreeMap.get("transferIn24H"));
            stringRedisTemplate.boundValueOps("filDTO").set(JSONUtil.toJsonStr(filDTO));
        }
    }

}

4. TestController

import com.google.gson.Gson;
import com.weixin.login.FilDTO;
import com.weixin.login.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author hanyulin
 * @apiNote
 * @date: 2021/9/11 11:31
 */
@RestController
@Api(tags = "测试")
public class TestController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @ApiOperation("抓取数据")
    @GetMapping(value = "/test")
    public R<FilDTO> test() {
        String filString = stringRedisTemplate.boundValueOps("filDTO").get();
        FilDTO filDTO = new Gson().fromJson(filString, FilDTO.class);
        return new R<>().ok(filDTO);
    }
}

5. 结果

在这里插入图片描述

四、Quartz

[定时任务框架Quartz]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值