springboot 快速啓動(八)——整合多線程開啓異步任務

一、定義線程池和開啓異步可用

Spring中存在一個接口AsyncConfigurer接口,該接口就是用來配置異步線程池的接口,它有兩個方法,getAsyncExecutor和getAsyncUncaughtExceptionHandler,第一個方法是獲取一個線程池,第二個方法是用來處理異步線程中發生的異常。它的源碼如下所示:

package org.springframework.scheduling.annotation;

import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.lang.Nullable;

public interface AsyncConfigurer {

	// 獲取線程池
	@Nullable
	default Executor getAsyncExecutor() {
		return null;
	}

	// 異步異常處理器
	@Nullable
	default AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return null;
	}
}

一般寫法:

實現上面異步接口
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        // 自定義線程池
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 核心線程數
        taskExecutor.setCorePoolSize(10);
        // 最大線程數
        taskExecutor.setMaxPoolSize(30);
        // 線程隊列最大線程數
        taskExecutor.setQueueCapacity(2000);
        // 初始化線程池
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            log.error("Error Occurs in async method:{}", ex.getMessage());
        };
    }
}

這時我們在config類上使用了@EnableAsync註解,當在spring中注入改bean時就會開啓異步任務

測試異步可用機制

service層

public interface AsyncService {

    /**
     * 模擬生成報表的異步方法
     */
    void testAsync();

}

實現層

import cn.itlemon.springboot.async.service.AsyncService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
@Service
public class AsyncServiceImpl implements AsyncService {

    @Override
    @Async("getAsyncExecutor")
    public void testAsync() {
        // 打印線程名稱
        System.out.println("線程名稱:【" + Thread.currentThread().getName() + "】");
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章