java 自定义线程池

143 阅读2分钟

概念

线程池,是一种线程的使用模式,它为了降低线程使用中频繁的创建和销毁所带来的资源消耗与代价。  
通过创建一定数量的线程,让他们时刻准备就绪等待新任务的到达,而任务执行结束之后再重新回来继续待命。
这就是线程池最核心的设计思路,[复用线程,平摊线程的创建与销毁的开销代价。]

自定义线程池代码实现

yml增加配置

task:
  pool:
    core-pool-size: 8    # 核心线程池大小
    max-pool-size: 50    # 最大线程数
    keep-alive-seconds: 60    # 活跃时间
    queue-capacity: 50    # 队列容量

自定义线程池

package cn.zy.study.thread.threadAsyn;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义线程池
 */
@Data
@Component
@ConfigurationProperties(prefix = "task.pool")
@EnableAsync
@Slf4j
public class TaskExecutePool implements AsyncConfigurer {

    private int corePoolSize;

    private int maxPoolSize;

    private int keepAliveSeconds;

    private int queueCapacity;

    @Override
    @Bean("myTaskAsyncPool")
    public ThreadPoolTaskExecutor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(corePoolSize);
        //最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //队列容量
        executor.setQueueCapacity(keepAliveSeconds);
        //活跃时间
        executor.setKeepAliveSeconds(queueCapacity);
        //线程名字前缀
        executor.setThreadNamePrefix("MyExecutor-");

        /**
         * 设置线程池拒绝策略
         * https://juejin.cn/post/7090570473611722788
         */
        // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }


    /**
     * 异步任务中异常处理
     *
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {
            log.error("Exception message - {}", throwable.getMessage());
            log.error("Method name - {}", method.getName());
            log.error("Parameter values - {}", Arrays.toString(objects));
            if (throwable instanceof Exception) {
                Exception exception = (Exception) throwable;
                log.error("exception:{}", exception.getMessage());
            }
            throwable.printStackTrace();
        };
    }
}

使用示例代码

package cn.zy.study.thread.threadAsyn;

import cn.hutool.core.date.StopWatch;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
public class UseThreadTest {

    @Autowired
    ThreadPoolTaskExecutor myTaskAsyncPool;

    /**
     * 阻塞 串行执行
     */
    public void test1() {
        StopWatch sw = new StopWatch();
        sw.start();
        List<Integer> list = Arrays.asList(1, 2, 3);
        // 2. 提交任务
        List<String> results = list.stream()
                .map(key ->
                        CompletableFuture.supplyAsync(() -> {
                            // 睡眠一秒,模仿处理过程
                            System.out.println(Thread.currentThread().getName());
                            try {
                                Thread.sleep(10000L);
                            } catch (InterruptedException e) {
                            }
                            return "结果" + key;
                        }, myTaskAsyncPool))
                .map(CompletableFuture::join).collect(Collectors.toList());
        // 3. 获取结果
        System.out.println(results);
        sw.stop();
        System.out.println("耗时:" + sw.getTotalTimeMillis());
    }

    /**
     * 异步执行
     */
    public void test2() {
        StopWatch sw = new StopWatch();
        sw.start();

        List<Integer> list = Arrays.asList(1, 2, 3);
        CompletableFuture[] array = list.stream()
                .map(key ->
                        CompletableFuture.supplyAsync(() -> {
                            System.out.println("当前线程:" + Thread.currentThread().getName());
                            // 睡眠一秒,模仿处理过程
                            try {
                                Thread.sleep(10000L);
                            } catch (Exception e) {
                            }
                            return "结果" + key;
                        }, myTaskAsyncPool))
                .toArray(CompletableFuture[]::new);
        // 2. 提交任务,并调用join()阻塞等待所有任务执行完成
        Set<String> collect = Arrays.stream(array)
                .map(completableFuture -> {
                    String result;
                    try {
                        result = (String) completableFuture.get();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    return result;
                }).collect(Collectors.toSet());
        System.out.println(new Gson().toJson(collect));
        CompletableFuture.allOf(array).join();
        sw.stop();
        System.out.println("耗时:" + sw.getTotalTimeMillis());
    }
}