Java微服务生学教育-团队博客

使用 Spring-Boot 自定义一个线程池

2018-07-31  本文已影响135人  古拉里

第一步,先定义一个线程池

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;

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

    /**
     * 声明一个线程池
     *
     * @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;
    }
}

第二步,创建一个需要执行方法类

一定要将线程执行方法单独放置一个Class是因为,使用了 AOP,线程池配置通过注解扫描配置;所以不许要有依赖注入的动作,才会触发调用线程池的配置;不要忘了哦!

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 {


    /**
     * 普通任务,无返回结果
     *
     * @param data
     */
    @Async("taskExecutor")
    public void doTaskOne(String data) {
        try {
            log.info("开始做任务1");
            Stopwatch sw = Stopwatch.createStarted();

            Thread.sleep(5000);

            log.info("完成任务1, 耗时:{}", sw.stop());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 有返回结果,通过 AsyncResult 异步获取
     *
     * @param data
     * @return
     */
    @Async("taskExecutor")
    public Future<String> doTaskTwo(String data) {
        try {
            log.info("开始做任务2");
            Stopwatch sw = Stopwatch.createStarted();

            Thread.sleep(5000);

            log.info("完成任务2, 耗时:{}", sw.stop());

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

第三步,执行 run 方法,详细的单元测试

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;

/**
 * 单元测试
 *
 * @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("开始请求任务1");
        Stopwatch sw = Stopwatch.createStarted();

        simpleTask.doTaskOne("12345");

        log.info("完成请求任务1, 耗时:{}", sw.stop());

    }

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

        log.info("开始请求任务2");
        Stopwatch sw = Stopwatch.createStarted();

        Future<String> feature = simpleTask.doTaskTwo("12345");
        while (true) {
            if (feature.isDone()) {
                log.info("完成请求任务2,返回结果:{}, 耗时:{}", feature.get(), sw.stop());
                break;
            }
        }
    }

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

        log.info("开始请求任务2");
        Stopwatch sw = Stopwatch.createStarted();

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

        String result = feature.get(10, TimeUnit.SECONDS);
        log.info("完成请求任务2,返回结果:{}, 耗时:{}", result, sw.stop());
    }
}

源代码参考提供

以上实例见源代码:https://github.com/gumutianqi/springboot2-learn/tree/master/spring-boot2-threadpool

上一篇 下一篇

猜你喜欢

热点阅读