Spring Boot 整合定時任務和異步任務處理


1.定時任務

Spring Boot 使用注解方式開啟定時任務,分為3步

1)啟動類里面加上 @EnableScheduling 注解開啟定時任務,自動掃描標記了@Scheduled 注解的方法

@SpringBootApplication
@EnableScheduling public class BaseProjectApplication {

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

}

2)定時任務業務類加上 @Component 注解,用於被容器掃描

3)定時執行的方法加上注解 @Scheduled(fixedRate=2000) 定期執行一次

@Component public class TestTask {
    
    @Scheduled(fixedRate=2000)//兩秒執行一次
    public void sum() throws InterruptedException{
        System.out.println("結束 當前時間:"+new Date());

    }
}       

常用定時任務表達式配置

(1)fixedRate: 定時多久執行一次(上一次開始執行時間點后xx毫秒再次執行)

(2)fixedRateString: 定時多久執行一次(上一次開始執行時間點后xx毫秒再次執行),字符串形式,可以通過配置文件指定

(3)fixedDelay: 定時多久執行一次(上一次執行結束時間點后xx毫秒再次執行)

(4)fixedDelayString: 定時多久執行一次(上一次執行結束時間點后xx毫秒再次執行),字符串形式,可以通過配置文件指定

(5)cron 定時任務表達式 @Scheduled(cron="*/1 * * * * *") 表示每秒。crontab 工具 https://tool.lu/crontab/

@Scheduled(fixedRate=2000)//兩秒執行一次
@Scheduled(fixedRateString="2000")//兩秒執行一次

@Scheduled(fixedDelay=2000)//兩秒執行一次
@Scheduled(fixedDelayString="2000")//兩秒執行一次

@Scheduled(cron="*/2 * * * * *")//每兩秒執行一次

 

2.異步任務

Spring Boot 使用注解方式開啟異步任務,分為3步

1)啟動類里面加上 @EnableAsync 注解開啟異步任務,自動掃描標記了 @Async 注解的方法

@SpringBootApplication 
@EnableAsync //開啟異步任務
public class XdclassApplication {
    public static void main(String[] args) {
        SpringApplication.run(XdclassApplication.class, args);
    }
}

2)異步任務業務類加上 @Component 注解,用於被容器掃描

3)異步執行的方法加上注解 @Async 表示該方法可以異步執行,也可以在異步任務業務類加上 @Async 表示該類中的所有方法可以異步執行

@Component
@Async public class AsyncTask {
    
    public void task1() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(1000L);
        long end = System.currentTimeMillis();
        System.out.println("任務1耗時="+(end-begin));
    }
    
    public void task2() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(2000L);
        long end = System.currentTimeMillis();
        System.out.println("任務2耗時="+(end-begin));
    } 
    
    public void task3() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(3000L);
        long end = System.currentTimeMillis();
        System.out.println("任務3耗時="+(end-begin));
    }
    
    
    //獲取異步結果
    public Future<String> task4() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(2000L);
        long end = System.currentTimeMillis();
        System.out.println("任務4耗時="+(end-begin));
        return new AsyncResult<String>("任務4");
    }
    
    
    public Future<String> task5() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(3000L);
        long end = System.currentTimeMillis();
        System.out.println("任務5耗時="+(end-begin));
        return new AsyncResult<String>("任務5");
    }
    
    public Future<String> task6() throws InterruptedException{
        long begin = System.currentTimeMillis();
        Thread.sleep(1000L);
        long end = System.currentTimeMillis();
        System.out.println("任務6耗時="+(end-begin));
        return new AsyncResult<String>("任務6");
    }
    
}

測試代碼如下:

@RestController
@RequestMapping("/api/v1")
public class UserController {
    @Autowired
    private AsyncTask task;
    
    @GetMapping("async_task")
    public JsonData exeTask() throws InterruptedException{
        
        long begin = System.currentTimeMillis();
        
//        task.task1();
//        task.task2();
//        task.task3();

        Future<String> task4 = task.task4();
        Future<String> task5 = task.task5();
        Future<String> task6 = task.task6();
        for(;;){
            if (task4.isDone() && task5.isDone() && task6.isDone()) {
                break;
            }
        }
        
        long end = System.currentTimeMillis();
        
        long total = end-begin;
        System.out.println("執行總耗時="+total);
        return JsonData.buildSuccess(total);
    }
}

注意點:

1)要把異步任務封裝到類里面,不能直接寫到 Controller

2)增加 Future<String>  返回結果 AsyncResult<String>("task執行完成"); 

3)如果需要拿到結果,需要判斷全部的 task.isDone();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM