ThreadPoolExecutor实现多线程+实战

平时项目开发中,接口业务逻辑复杂,sql也没有了优化空间,这时我们就可以用到多线程来并行处理,提升接口效率,这里做个记录

一、使用场景

  1. 定时任务批量处理数据

  1. 复杂逻辑需要多个条件判断

  1. MQ消费

二、接口实现(封装一个通用工具类AsyncThreadUtils)

public class AsyncThreadUtils {

    private static final int corePoolSize = Runtime.getRuntime().availableProcessors();//CPU核心数
    private static final int maximumPoolSize = corePoolSize * 2;
    private static long keepAliveTime = 1;
    private static TimeUnit keepAliveTimeUnit = TimeUnit.MINUTES;
    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1024);
    private static RejectedExecutionHandler rejectedHandler = new ThreadPoolExecutor.CallerRunsPolicy();

    /**
     * corePoolSize : 线程池核心线程数,最好默认CPU核心数
     * maximumPoolSize : 线程池最大线程数,最好是核心线程数的两倍,太多会引起线程切换
     * keepAliveTime : 大于核心线程数的空闲线程存活时间
     * keepAliveTimeUnit : 空闲线程存活时间的单位(秒、分钟、小时等等)
     * workQueue : 线程池有界队列,新任务没有可用线程处理时会把任务放到该队列中,等待被处理
     * rejectedHandler : 拒绝处理策略,默认直接丢弃并抛出异常-AbortPolicy,调用者线程直接处理-CallerRunsPolicy
     */
    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
            corePoolSize,
            maximumPoolSize,
            keepAliveTime,
            keepAliveTimeUnit,
            workQueue,
            rejectedHandler
    );

    /**
     * 直接提交任务,无返回值
     * @param task
     */
    public static void submit(Runnable task){
        poolExecutor.submit(task);
    }

    /**
     * 提交任务,返回泛型结果
     * @param task
     * @param <T>
     * @return
     */
    public static <T> Future<T> submit(Callable<T> task){
        return poolExecutor.submit(task);
    }
}

三、Controller层测试多线程

@RestController
@RequestMapping(value = "/threadPool")
public class ThreadPoolController {
    private static final Log LOG = LogFactory.getLog(ThreadPoolController.class);

    @ApiOperation("测试多线程并发处理")
    @RequestMapping(value = "/ceshiThread")
    public ResultMsg ceshiThread(){
        try {
            int finalI = 0;
            for (int i = 0; i < 20; i++) {
                finalI ++;
                int finalI1 = finalI;
                AsyncThreadUtils.submit(() -> c(finalI1));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResultUtil.success(null);
    }

    @ApiOperation("测试多线程异步处理")
    @RequestMapping(value = "/ceshiAsync")
    public ResultMsg ceshiAsync(){
        int a = 1;
        try {
            long currentTimeMillis = System.currentTimeMillis();
            a();
            b();
            long currentTimeMillis1 = System.currentTimeMillis();
            LOG.error("同步耗时:"+ (currentTimeMillis1 - currentTimeMillis));
            long currentTimeMillis2 = System.currentTimeMillis();
            Future<Boolean> submit = AsyncThreadUtils.submit(() -> a());
            Future<Boolean> submit2 = AsyncThreadUtils.submit(() -> b());
            Boolean aBoolean = submit.get();
            Boolean aBoolean2 = submit2.get();
            long currentTimeMillis3 = System.currentTimeMillis();
            LOG.error("异步耗时:"+ (currentTimeMillis3 - currentTimeMillis2));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResultUtil.success(null);
    }

    private Boolean a(){
        try {
            Thread.sleep(3000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return false;
    }

    private Boolean b(){
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return false;
    }

    private Boolean c(int count){
        try {
            Thread.sleep(5000);
            LOG.error("打印:"+ count);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return false;
    }
}

多线程并行处理任务可以提升服务器资源使用率,同时可以提高接口响应效率,值得推荐!!!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值