亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot :定時任務詳解

發布時間:2020-07-18 12:00:44 來源:網絡 閱讀:774 作者:Java_老男孩 欄目:編程語言

SpringBoot?是為了簡化?Spring?應用的創建、運行、調試、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規范,引入相關的依賴就可以輕易的搭建出一個 WEB 工程

在我們日常開發中,經常會遇到?數據定時增量同步、定時發送郵件、爬蟲定時抓取 的需求;這時我們可以采用定時任務的方式去進行工作…..

定時任務概述

定時任務:顧名思義就是在指定/特定的時間進行工作,比如我們的手機鬧鐘,它就是一種定時任務。

實現方式

Timer:?JDK自帶的java.util.Timer;通過調度java.util.TimerTask的方式?讓程序按照某一個頻度執行,但不能在指定時間運行。?一般用的較少。

ScheduledExecutorService:?JDK1.5新增的,位于java.util.concurrent包中;是基于線程池設計的定時任務類,每個調度任務都會被分配到線程池中,并發執行,互不影響。

Spring Task:?Spring3.0 以后新增了task,一個輕量級的Quartz,功能夠用,用法簡單。

Quartz:?功能最為強大的調度器,可以讓程序在指定時間執行,也可以按照某一個頻度執行,它還可以動態開關,但是配置起來比較復雜。現如今開源社區中已經很多基于Quartz 實現的分布式定時任務項目(xxl-job、elastic-job)。

Timer 方式

基于?Timer?實現的定時調度,基本就是手擼代碼,目前應用較少,不是很推薦

package com.battcn.timer;

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

/**
 * 基于Timer實現的定時調度(不推薦,用該方式不如用 ScheduledExecutorService )
 *
 * @author Levin
 * @since 2018/5/29 0029
 */
public class TimerDemo {

    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("執行任務:" + LocalDateTime.now());
            }
        };
        Timer timer = new Timer();
        // timerTask:需要執行的任務
        // delay:延遲時間(以毫秒為單位)
        // period:間隔時間(以毫秒為單位)
        timer.schedule(timerTask, 5000, 3000);
    }
}

基于 ScheduledExecutorService

Timer很類似,但它的效果更好,多線程并行處理定時任務時,Timer運行多個TimeTask時,只要其中有一個因任務報錯沒有捕獲拋出的異常,其它任務便會自動終止運行,使用 ScheduledExecutorService 則可以規避這個問題

package com.battcn.scheduled;

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

/**
 * 基于 ScheduledExecutorService 方式,相對的比 Timer 要好
 *
 * @author Levin
 * @since 2018/5/29 0029
 */
public class ScheduledExecutorServiceDemo {

    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
        // 參數:1、具體執行的任務   2、首次執行的延時時間
        //      3、任務執行間隔     4、間隔時間單位
        service.scheduleAtFixedRate(() -> System.out.println("執行任務A:" + LocalDateTime.now()), 0, 3, TimeUnit.SECONDS);
    }
}

Spring Task(本章關鍵)

導入依賴

在?pom.xml?中添加?spring-boot-starter-web?依賴即可,它包含了spring-context,定時任務相關的就屬于這個JAR下的org.springframework.scheduling包中

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

定時任務

@Scheduled?定時任務的核心

  • cron:?cron表達式,根據表達式循環執行,與fixedRate屬性不同的是它是將時間進行了切割。(@Scheduled(cron = "0/5 * * * * *")任務將在5、10、15、20...這種情況下進行工作)
  • fixedRate:?每隔多久執行一次,無視工作時間(@Scheduled(fixedRate = 1000)?假設第一次工作時間為2018-05-29 16:58:28,工作時長為3秒,那么下次任務的時候就是2018-05-29 16:58:31
  • fixedDelay:?當前任務執行完畢后等待多久繼續下次任務(@Scheduled(fixedDelay = 3000)?假設第一次任務工作時間為2018-05-29 16:54:33,工作時長為5秒,那么下次任務的時間就是2018-05-29 16:54:41
  • initialDelay:?第一次執行延遲時間,只是做延遲的設定,與fixedDelay關系密切,配合使用,相輔相成。

@Async?代表該任務可以進行異步工作,由原本的串行改為并行

package com.battcn.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 基于 Spring 自帶的
 *
 * @author Levin
 * @since 2018/5/29 0029
 */
@Component
public class SpringTaskDemo {

    private static final Logger log = LoggerFactory.getLogger(SpringTaskDemo.class);

    @Async
    @Scheduled(cron = "0/1 * * * * *")
    public void scheduled1() throws InterruptedException {
        Thread.sleep(3000);
        log.info("scheduled1 每1秒執行一次:{}", LocalDateTime.now());
    }

    @Scheduled(fixedRate = 1000)
    public void scheduled2() throws InterruptedException {
        Thread.sleep(3000);
        log.info("scheduled2 每1秒執行一次:{}", LocalDateTime.now());
    }

    @Scheduled(fixedDelay = 3000)
    public void scheduled3() throws InterruptedException {
        Thread.sleep(5000);
        log.info("scheduled3 上次執行完畢后隔3秒繼續執行:{}", LocalDateTime.now());
    }

}

cron表達式在線生成:?http://www.pdtools.net/tools/becron.jsp

主函數

@EnableScheduling?注解表示開啟對@Scheduled注解的解析;同時new ThreadPoolTaskScheduler()也是相當的關鍵,通過閱讀過源碼可以發現默認情況下的?private volatile int poolSize = 1;這就導致了多個任務的情況下容易出現競爭情況(多個任務的情況下,如果第一個任務沒執行完畢,后續的任務將會進入等待狀態)。

@EnableAsync?注解表示開啟@Async注解的解析;作用就是將串行化的任務給并行化了。(@Scheduled(cron = "0/1 * * * * *")假設第一次工作時間為2018-05-29 17:30:55,工作周期為3秒;如果不加@Async那么下一次工作時間就是2018-05-29 17:30:59;如果加了@Async?下一次工作時間就是2018-05-29 17:30:56

package com.battcn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

/**
 * @author Levin
 */
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class Chapter15Application {

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

    /**
     * 很關鍵:默認情況下 TaskScheduler 的 poolSize = 1
     *
     * @return 線程池
     */
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }
}

測試

完成準備事項后,啟動Chapter15Application,觀察日志信息如下

2018-05-29 17:35:51.479  INFO 32640 --- [taskScheduler-1] com.battcn.task.SpringTaskDemo           : scheduled2 每1秒執行一次:2018-05-29T17:35:51.479
2018-05-29 17:35:52.005  INFO 32640 --- [taskScheduler-3] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:52.005
2018-05-29 17:35:53.002  INFO 32640 --- [taskScheduler-5] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:53.002
2018-05-29 17:35:53.468  INFO 32640 --- [taskScheduler-2] com.battcn.task.SpringTaskDemo           : scheduled3 上次執行完畢后隔3秒繼續執行:2018-05-29T17:35:53.468
2018-05-29 17:35:54.002  INFO 32640 --- [taskScheduler-6] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:54.002
2018-05-29 17:35:54.479  INFO 32640 --- [taskScheduler-7] com.battcn.task.SpringTaskDemo           : scheduled2 每1秒執行一次:2018-05-29T17:35:54.479
2018-05-29 17:35:55.002  INFO 32640 --- [taskScheduler-8] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:55.002
2018-05-29 17:35:56.001  INFO 32640 --- [taskScheduler-1] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:56.001
2018-05-29 17:35:57.001  INFO 32640 --- [taskScheduler-3] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:57.001
2018-05-29 17:35:57.479  INFO 32640 --- [taskScheduler-7] com.battcn.task.SpringTaskDemo           : scheduled2 每1秒執行一次:2018-05-29T17:35:57.479
2018-05-29 17:35:58.003  INFO 32640 --- [taskScheduler-4] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:58.003
2018-05-29 17:35:59.001  INFO 32640 --- [taskScheduler-5] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:35:59.001
2018-05-29 17:36:00.002  INFO 32640 --- [taskScheduler-6] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:36:00.002
2018-05-29 17:36:00.480  INFO 32640 --- [taskScheduler-7] com.battcn.task.SpringTaskDemo           : scheduled2 每1秒執行一次:2018-05-29T17:36:00.480
2018-05-29 17:36:01.001  INFO 32640 --- [taskScheduler-8] com.battcn.task.SpringTaskDemo           : scheduled1 每1秒執行一次:2018-05-29T17:36:01.001
2018-05-29 17:36:01.470  INFO 32640 --- [taskScheduler-9] com.battcn.task.SpringTaskDemo           : scheduled3 上次執行完畢后隔3秒繼續執行:2018-05-29T17:36:01.470

總結

目前很多大佬都寫過關于?SpringBoot?的教程了,如有雷同,請多多包涵,本教程基于最新的?spring-boot-starter-parent:2.0.2.RELEASE編寫,包括新版本的特性都會一起介紹…

本文的重點是你有沒有收獲與成長,其余的都不重要,希望讀者們能謹記這一點。同時我經過多年的收藏目前也算收集到了一套完整的學習資料,包括但不限于:分布式架構、高可擴展、高性能、高并發、Jvm性能調優、Spring,MyBatis,Nginx源碼分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多個知識點高級進階干貨,希望對想成為架構師的朋友有一定的參考和幫助

有需要的可以加一下三千人Java技術交流分享群:“708 701 457”免費獲取

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桂东县| 鄂伦春自治旗| 古浪县| 陆川县| 白河县| 怀远县| 汕头市| 青岛市| 东海县| 大洼县| 黄浦区| 奉贤区| 金山区| 台南市| 黄冈市| 松阳县| 庆阳市| 衡东县| 娱乐| 泰兴市| 吉木萨尔县| 博罗县| 应城市| 布尔津县| 东平县| 牟定县| 裕民县| 邹平县| 搜索| 昔阳县| 肇源县| 常熟市| 南澳县| 陕西省| 玛沁县| 曲水县| 丰都县| 文登市| 馆陶县| 田东县| 大田县|