使用 Spring-Boot 自定義一個(gè)線程池

第一步,先定義一個(gè)線程池

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定義一個(gè)線程池
 *
 * @author LarryKoo (larrykoo@126.com)
 * @date 2017/12/25 14:21
 * @slogon 站在巨人的肩膀上
 * @since 1.0.0
 */
@EnableAsync
@Configuration
public class TaskPoolConfig {

    /**
     * 聲明一個(gè)線程池
     *
     * @return
     */
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("taskExecutor-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(10);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

第二步,創(chuàng)建一個(gè)需要執(zhí)行方法類

一定要將線程執(zhí)行方法單獨(dú)放置一個(gè)Class是因?yàn)?,使用?AOP,線程池配置通過(guò)注解掃描配置;所以不許要有依賴注入的動(dòng)作,才會(huì)觸發(fā)調(diào)用線程池的配置;不要忘了哦!

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;

/**
 * SimpleTask
 *
 * @author LarryKoo (larrykoo@126.com)
 * @date 2017/12/25 14:21
 * @slogon 站在巨人的肩膀上
 * @since 1.0.0
 */
@Slf4j
@Component
public class SimpleTask {


    /**
     * 普通任務(wù),無(wú)返回結(jié)果
     *
     * @param data
     */
    @Async("taskExecutor")
    public void doTaskOne(String data) {
        try {
            log.info("開(kāi)始做任務(wù)1");
            Stopwatch sw = Stopwatch.createStarted();

            Thread.sleep(5000);

            log.info("完成任務(wù)1, 耗時(shí):{}", sw.stop());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 有返回結(jié)果,通過(guò) AsyncResult 異步獲取
     *
     * @param data
     * @return
     */
    @Async("taskExecutor")
    public Future<String> doTaskTwo(String data) {
        try {
            log.info("開(kāi)始做任務(wù)2");
            Stopwatch sw = Stopwatch.createStarted();

            Thread.sleep(5000);

            log.info("完成任務(wù)2, 耗時(shí):{}", sw.stop());

            return new AsyncResult<>(data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

第三步,執(zhí)行 run 方法,詳細(xì)的單元測(cè)試

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import me.weteam.threadpool.task.SimpleTask;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 單元測(cè)試
 *
 * @author LarryKoo (larrykoo@126.com)
 * @date 2018/08/03 14:21
 * @slogon 站在巨人的肩膀上
 * @since 1.0.0
 */
@Slf4j
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ThreadTestCase {

    @Autowired
    private SimpleTask simpleTask;

    @Test
    public void testRunTaskOne() {
        log.info("================= run_task_one =======================");
        log.info("開(kāi)始請(qǐng)求任務(wù)1");
        Stopwatch sw = Stopwatch.createStarted();

        simpleTask.doTaskOne("12345");

        log.info("完成請(qǐng)求任務(wù)1, 耗時(shí):{}", sw.stop());

    }

    @Test
    public void testRunTaskTwo() throws ExecutionException, InterruptedException {
        log.info("================= run_task_two =======================");

        log.info("開(kāi)始請(qǐng)求任務(wù)2");
        Stopwatch sw = Stopwatch.createStarted();

        Future<String> feature = simpleTask.doTaskTwo("12345");
        while (true) {
            if (feature.isDone()) {
                log.info("完成請(qǐng)求任務(wù)2,返回結(jié)果:{}, 耗時(shí):{}", feature.get(), sw.stop());
                break;
            }
        }
    }

    @Test
    public void testRunTaskTwoPlus() throws ExecutionException, InterruptedException, TimeoutException {
        log.info("================= run_task_two_plus =======================");

        log.info("開(kāi)始請(qǐng)求任務(wù)2");
        Stopwatch sw = Stopwatch.createStarted();

        Future<String> feature = simpleTask.doTaskTwo("12345");

        String result = feature.get(10, TimeUnit.SECONDS);
        log.info("完成請(qǐng)求任務(wù)2,返回結(jié)果:{}, 耗時(shí):{}", result, sw.stop());
    }
}

源代碼參考提供

以上實(shí)例見(jiàn)源代碼:https://github.com/gumutianqi/springboot2-learn/tree/master/spring-boot2-threadpool

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,253評(píng)論 6 342
  • 自己通過(guò)shell修改hosts文件時(shí)總是提示ReadOnly最終通過(guò)以下的方式修改成功 1、終端定位emulat...
    McLiu624閱讀 1,294評(píng)論 1 0
  • 人間至味是清歡,我要向周潤(rùn)發(fā)學(xué)習(xí),活得明白的人一定是素與簡(jiǎn)。 要砍掉身體與靈魂上多余的東西,比如名利心,虛榮心,貪...
    知識(shí)管理某李閱讀 279評(píng)論 0 2
  • (六十四)是姐理虧 (六十五)安樂(lè)郡主 我開(kāi)鍋的漿糊腦袋,在昭汐連消帶打的說(shuō)詞中,也漸漸平息了下來(lái)。 在昭汐訓(xùn)話完...
    筆間流年閱讀 313評(píng)論 0 1

友情鏈接更多精彩內(nèi)容