Spring Boot 使用Spring的異步線程池

前言

線程池,從名字上來看,就是一個保存線程的"池子",凡事都有其道理,那線程池的好處在哪裏呢?java

咱們要讓計算機爲咱們幹一些活,其實都是在使用線程,使用方法就是new一個Runnable接口或者新建一個子類,繼承於Thread類,這就會涉及到線程對象的建立與銷燬,這兩個操做無疑是耗費咱們系統處理器資源的,那如何解決這個問題呢? 線程池其實就是爲了解決這個問題而生的。spring

線程池提供了處理系統性能和大用戶量請求之間的矛盾的方法,經過對多個任務重用已經存在的線程對象,下降了對線程對象建立和銷燬的開銷,因爲當客戶請求到了時,線程對象已經存在,能夠提升請求的響應時間從而總體的提升了系統服務的表現。bash

本篇博客就是要總結一下,如何在Spring中使用異步線程池,給你們一個例子,去體會一下異步這個概念app

實習生小王負責後臺管理系統的報表分析,他的工做是負責操做後臺系統,點擊按鈕,生成數據報表,而並不須要查看報表,因爲數據量大, 生成報表須要花費很長時間,而若是生成報表和其餘工做在一個線程,小王就沒法幹其餘工做了,因此須要將生成報表這個任務交給計算機的其餘線程,這即是異步的體現。異步

在Spring中使用異步線程池async

spring中提供了AsyncConfigurer這個配置接口,便於咱們配置本身的異步線程池。ide

新建異步配置類

我習慣新建一個config包,而後將一些組件的配置類都放到裏面性能

package com.example.wyh.config;

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.concurrent.Executor;

/**
 * @author 陽光大男孩!!!
 */
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        //定義線程池
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        //設置核心線程數
        threadPoolTaskExecutor.setCorePoolSize(10);
        //設置線程池最大線程數
        threadPoolTaskExecutor.setMaxPoolSize(30);
        //設置線程隊列最大線程數
        threadPoolTaskExecutor.setQueueCapacity(2000);
        //初始化線程池
        threadPoolTaskExecutor.initialize();

        return threadPoolTaskExecutor;
    }
}

複製代碼

在上面代碼中,咱們使用@Configuration告訴spring這是一個配置類,使用註解@EnableAsync讓spring開啓異步可用。 這樣之後若是想把某個方法中的任務異步地放到另一個線程,只須要經過方法上加 @Async註解便可。測試

新建一個服務接口,並實現

package com.example.wyh.Service;

/**
 * @author 陽光大男孩!!!
 */
public interface AsyncService {

    /**
     * 測試使用異步線程池來執行工做
     */
    public void useAsyncThreadWork();
    
}
複製代碼
package com.example.wyh.Service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @author 陽光大男孩!!!
 */
@Service
public class AsyncServiceImp implements AsyncService{

    @Override
    @Async
    public void useAsyncThreadWork() {
        System.out.println(Thread.currentThread().getName());

    }
}
複製代碼

在接口的具體實現中,咱們打印了當前線程的名稱,藉以來查看是不是在一個心的線程中執行該任務。而且經過@Service註解告訴spring這是一個Service類型的bean,這樣咱們就可讓spring經過其自身容器來管理咱們的對象,這就是IOC特性的一個體現。ui

新建一個Controller 進行訪問、測試

/**
 * @author 陽光大男孩!!!
 */
@RestController
public class AsyncController {

    @Autowired
    AsyncService asyncService;
    @GetMapping("/testAsync")
    public String testAsync()
    {
        System.out.println(Thread.currentThread().getName());
        asyncService.useAsyncThreadWork();
        return "testAsync方法執行成功...";
    }
}

複製代碼

能夠看到,在上述代碼中,咱們使用 @Autowired註解自動裝配了剛纔交給Spring容器管理的Service實現類對象,這是spring 的DI特性體現。

因爲我開的是8090端口,因此我訪問的是8090端口

能夠看到打印了兩個線程的名稱,第一個是在Controller中執行的線程名稱,第二個則是spring經過咱們剛纔的配置,爲咱們從線程池中提取的線程併爲咱們執行相應任務。

總結

本篇博客簡介了在spring中使用線程池異步執行任務的基本方法,爲在項目中使用異步線程池提供了示例。

最後

上面都是本身整理好的!我就把資料貢獻出來給有須要的人!順便求一波關注,哈哈~各位小夥伴關注我後私信【Java】就能夠免費領取噠 博主:陽光大男孩 原文連接: blog.csdn.net/weixin_4388…
相關文章
相關標籤/搜索