线程池使用

线程池使用

1、在“application.yml”配置中添加线程配置

spring:
  threadpool:
    corePoolSize: 2 #线程池里最小线程数
    maxPoolSize: 5  #线程池最大数量
    keepAliveSeconds: 60 #线程最大的存活时间
    queueCapacity: 120 #队列的最大长度
    namePrefix: demoaTask #线程池名称前缀

2、添加配置类

在这里插入图片描述

2.1、AsyncTaskExecutePool.java

package com.sgcc.dlsc.demoa.config.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 陈星
 * @version 1.0
 * @date 2019-9-4 16:04:31
 * @Description 注意:该线程池被所有的异步任务共享,而不属于某一个异步任务,       可通过在方法上使用@Async 注解调用
 * 配置异步任务的线程池
 */
@Slf4j
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer {

    @Autowired
    private TaskThreadPoolConfig config; // 配置属性类,见上面的代码

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(config.getCorePoolSize());
        executor.setMaxPoolSize(config.getMaxPoolSize());
        executor.setQueueCapacity(config.getQueueCapacity());
        executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
        executor.setThreadNamePrefix("DefaltPool-");

        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {// 异步任务中异常处理
        return new AsyncUncaughtExceptionHandler() {

            @Override
            public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
                log.error("==========================" + arg0.getMessage() + "=======================", arg0);
                log.error("exception method:" + arg1.getName());
            }
        };
    }
}

2.2、TaskExecutePool.java

package com.sgcc.dlsc.demoa.config.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 陈星
 * @version 1.0
 * @date 2019-9-4 16:04:31
 * @Description 自定义线程池实现
 */
@Configuration
@Slf4j
@EnableAsync
public class TaskExecutePool {
    public final static String TaskExecutor = "TaskExecutor";
    @Autowired
    private TaskThreadPoolConfig config;

    @Bean(name = TaskExecutePool.TaskExecutor)
    public Executor gatewayTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        log.debug(config.toString());
        executor.setCorePoolSize(config.getCorePoolSize());
        executor.setMaxPoolSize(config.getMaxPoolSize());
        executor.setQueueCapacity(config.getQueueCapacity());
        executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
        executor.setThreadNamePrefix(config.getNamePrefix());

        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}

2.3、TaskThreadPoolConfig.java

package com.sgcc.dlsc.demoa.config.threadpool;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author 陈星
 * @version 1.0
 * @date 2019-9-4 16:04:31
 * @Description 自定义线程池配置工具类
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.threadpool") // 该注解的locations已经被启用,现在只要是在环境中,都会优先加载
public class TaskThreadPoolConfig {
    /**
     * 配置核心线程数
     */
    private int corePoolSize;
    /**
     * 配置最大线程数
     */
    private int maxPoolSize;
    /**
     * 配置线程空闲后的最大存活时间
     */
    private int keepAliveSeconds;
    /**
     * 配置队列大小
     */
    private int queueCapacity;
    /**
     * 配置线程池中的线程的名称前缀
     */
    private String namePrefix;
}

3、使用示范

3.1、编写service接口

package com.sgcc.dlsc.demoa.service;

/**
 * @Author 杨文培
 * @Date 2020/5/5 21:35
 * @Description
 */
public interface ThreadPoolService {
    /**
     * @Author 杨文培
     * @Description 线程池异步调用测试
     * @Date 21:36 2020/5/5
     **/
    void testThreadPool();
}

3.2、编写实现类

package com.sgcc.dlsc.demoa.service.impl;

import com.sgcc.dlsc.demoa.config.threadpool.TaskExecutePool;
import com.sgcc.dlsc.demoa.service.ThreadPoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @Author 杨文培
 * @Date 2020/5/5 21:36
 * @Description
 */
@Slf4j
@Service
public class ThreadPoolServiceImpl implements ThreadPoolService {
    /**
     * @Author 杨文培
     * @Description 线程池异步调用测试
     * @Date 21:36 2020/5/5
     **/
    @Async(TaskExecutePool.TaskExecutor)
    @Override
    public void testThreadPool() {
        log.info("我正在处理任务中");
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("任务处理完成");
    }
}

4、调用测试

package com.sgcc.dlsc.demoa.controller;

import com.sgcc.comm.util.ResultUtil;
import com.sgcc.dlsc.demoa.service.ThreadPoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 杨文培
 * @Date 2020/5/5 21:39
 * @Description
 */
@RestController
@Slf4j
@RequestMapping("/ThreadPool")
public class ThreadPoolController {
    @Autowired
    private ThreadPoolService threadPoolService;
    @PostMapping("/testThreadPool")
    public ResultUtil testThreadPool(){
        threadPoolService.testThreadPool();
        return ResultUtil.result("后台正在处理中,大约需要15秒钟");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值