Springboot中的多線程

Spring是通過任務執行器(TaskExecutor)來實現多線程和併發編程,使用ThreadPoolTaskExecutor來創建一個基於線城池的TaskExecutor。在使用線程池的大多數情況下都是異步非阻塞的。我們配置註解@EnableAsync可以開啓異步任務。然後在實際執行的方法上配置註解@Async上聲明是異步任務。

分爲三步:1.配置線程池管理 Executor ;2.配置異步方法;3.執行異步方法

1.配置線程池管理 Executor

新建一個配置類:

@Configuration
@EnableAsync
public class ThreadConfig {

    @Bean
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //設置線程池的大小
        executor.setCorePoolSize(5);
        //設置線程池的最大值
        executor.setMaxPoolSize(15);
        //設置線程池的最大值
        executor.setQueueCapacity(250);
        //初始換線程池
        executor.initialize();
        return executor;
    }
}

2.配置異步方法

@Service
public class AsyncTaskService {

    @Async("getAsyncExecutor")
    public void executeAsyncTask() {
        //do something
    }
}

3.執行異步方法

像正常調用方法即可

常見問題:

1.java.lang.InterruptedException: sleep interrupted

如果在測試類裏調用異步方法,可能會出現子線程還未執行完,父線程已經關閉。則可以在父線程裏增加Thread.sleep()方法,等一等子線程

2.Only one AsyncAnnotationBeanPostProcessor may exist within the context.

可能是對某個bean配置了多次,可以註釋掉 xml配置裏的 註解

<task:annotation-driven/>

3.Executor [java.util.concurrent.ThreadPoolExecutor@497ed877[Running, pool size = 15, active threads = 15, queued tasks = 20, completed tasks = 0]] did not accept task: org.springframework.aop.interceptor.AsyncExecutionInterceptor$$LambdaXXXX

可能是 “線程池的最大數+隊列數>你的併發數” ,你需要增加你的隊列容量, 

executor.setQueueCapacity(20); 將20調大即可

 

參考文獻 https://segmentfault.com/a/1190000015766938

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