美文网首页Java微服务生学教育-团队博客
使用 Spring-Boot 自定义一个线程池

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

作者: 古拉里 | 来源:发表于2018-07-31 11:47 被阅读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

相关文章

  • 线程池模板

    线程池自定义工厂 线程池管理 使用

  • spring boot中设置异步请求默认使用的线程池

    1、自定义异步线程池,如果不自定义则使用自带的线程池(不是真正意义上的线程池,不会复用线程) 2、springbo...

  • @EnabelAsync

    @EnabelAsync注解的使用。如不指定自定义异步线程池直接使用@EnableAsync即可使用,若自定义线程...

  • CompletableFuture使用方法

    一、自定义线程池 二、CompletableFuture使用

  • 线程池很容易理解的

    线程池介绍 并发队列 线程池原理分析 自定义线程池 文中部分代码使用 lambda 表达式以简化代码。 线程池 什...

  • Spring boot使用注解@Async实现异步调用

    1.自定义线程池 上面我们通过使用 ThreadPoolTaskExecutor创建了一个线程池,同时设置了以下这...

  • java线程池源码分析

    从线程池使用进行实现分析一.自定义线程池1.自定义线程池2.构造完成之后状态3.关键参数介绍二.执行任务1.exe...

  • 并发--共享模型之工具

    线程池 1.1 自定义线程池 先自定义任务队列 自定义线程池 测试: 定义拒绝策略接口: 1.2 ThreadPo...

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

    第一步,先定义一个线程池 第二步,创建一个需要执行方法类 一定要将线程执行方法单独放置一个Class是因为,使用了...

  • 多线程使用轮子

    构造一个对象,获取这个对象的list,然后循环去执行。 自定义线程池仓库 异步请求参数基类 线程池工具类 使用 建...

网友评论

    本文标题:使用 Spring-Boot 自定义一个线程池

    本文链接:https://www.haomeiwen.com/subject/kdgcvftx.html