Springboot的並行多任務


一般生產環境不會直接這么用,但是springboot提供的這個功能還是很有用的,比如說我們自己做並發測試,模擬定時任務。

其他依賴

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.0</version>
</dependency>

配置類

主要是為了初始化自定義的線程池,以及異步執行處理配置(單獨的使用@Schedule是單線程的,配合@Async實現任務並行)

import cn.hutool.core.thread.ThreadFactoryBuilder;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Random;
import java.util.concurrent.*;

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/8/21 18:23
 **/

@Configuration
@EnableAsync
public class ScheduleConfig implements AsyncConfigurer {
    /**
     * 根據系統核心數來設置線程數: private static int corePoolSize = Runtime.getRuntime().availableProcessors();
     * 核心線程數
     */
    private static int corePoolSize = 100;
    /**
     * 最大線程數
     */
    private static int maximumPoolSize = corePoolSize * 2;
    /**
     * 線程存活時間
     */
    private static long keepAliveTime = 101L;
    /**
     * 阻塞隊列大小
     */
    private static final int CAPACITY = 1000;
    /**
     * 線程池命名
     */
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNamePrefix("my-work-pool-").build();
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
            keepAliveTime, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(CAPACITY),
            namedThreadFactory,
            (r, executor) -> userDefinedRejectionPolicy(r));

    /**
     * 拒絕策略;當任務太多來不及處理時,如何拒絕任務;
     *
     * @param r Runnable
     */
    private static void userDefinedRejectionPolicy(Runnable r) {
        //1、AbortPolicy策略:該策略會直接拋出異常,阻止系統正常工作;
        //
        //2、CallerRunsPolicy策略:如果線程池的線程數量達到上限,該策略會把任務隊列中的任務放在調用者線程當中運行;
        //
        //3、DiscardOldestPolicy策略:該策略會丟棄任務隊列中最老的一個任務,也就是當前任務隊列中最先被添加進去的,馬上要被執行的那個任務,並嘗試再次提交;
        //
        //4、DiscardPolicy策略:該策略會默默丟棄無法處理的任務,不予任何處理。當然使用此策略,業務場景中需允許任務的丟失;
        System.out.println(r.toString() + "執行了拒絕策略");
        // TODO: 2020/8/19 這里寫拒絕策略的相關邏輯 ,在某些場景下我們應該盡量避免丟棄任務
    }

    @Override
    public Executor getAsyncExecutor() {
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }

}

任務執行類

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;

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/8/21 17:44
 **/
@Component
@EnableScheduling
@EnableAsync
public class MyTask {

    @Async
    @Scheduled(cron = "0/5 * *  * * ? ")
    public void mySchedule() {
        System.out.println("任務==1==");
        try {
            for (int i = 1; i <= 10; i++) {
                System.out.println("<==1==>" + i);
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async
    @Scheduled(cron = "0/5 * *  * * ? ")
    public void mySchedule2() {
        System.out.println("任務==2==");
        for (int i = 1; i <= 10; i++) {
            System.out.println("<==2==>" + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


免責聲明!

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



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