手动创新线程池ThreadPoolExecutor

根据阿里巴巴的JAVA开发手册推荐用ThreadPoolExecutor创建线程池(Executors 这个Java中的工具类创建的线程池,可能会耗费非常大的内存,甚至 OOM)

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class ThreadUtils {
    public static Integer someThreado(String str){
        long strat = System.currentTimeMillis();
        FutureTask<Integer> aFutureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return add("a",str);
            }
        });
        FutureTask<Integer> bFutureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return add("b",str);
            }
        });
        FutureTask<Integer> cFutureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return add("c",str);
            }
        });
/**
     * corePoolSize    线程池核心池的大小
     * maximumPoolSize 线程池中允许的最大线程数量
     * keepAliveTime   当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
     * unit            keepAliveTime 的时间单位
     * workQueue       用来储存等待执行任务的队列
     * threadFactory   创建线程的工厂类
     * handler         拒绝策略类,当线程池数量达到上线并且workQueue队列长度达到上限时就需要对到来的任务做拒绝处理
     * 原理:
     * 有请求时,创建线程执行任务,当线程数量等于corePoolSize时,请求加入阻塞队列里,当队列满了时,接着创建线程,
     * 线程数等于maximumPoolSize。 当任务处理不过来的时候,线程池开始执行拒绝策略。
     * 换言之,线程池最多同时并行执行maximumPoolSize的线程,最多处理maximumPoolSize+workQueue.size()的任务。多余的默认采用AbortPolicy会丢弃。
     * 阻塞队列:
     *   ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
     *   LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
     *   PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
     *   DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
     *   SynchronousQueue: 一个不存储元素的阻塞队列。
     *   LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
     *   LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。
     *   拒绝策略:
     *   ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
     *   ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
     *   ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务。(重复此过程)
     *   ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。
     */


        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 30, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>(300));
        threadPoolExecutor.submit(aFutureTask);
        threadPoolExecutor.submit(bFutureTask);
        threadPoolExecutor.submit(cFutureTask);
        log.info("当前活动线程数:{},线程池线程数量:{}",threadPoolExecutor.getActiveCount(),threadPoolExecutor.getPoolSize());
        Integer res = 0;
        try {
            Integer a = aFutureTask.get();
            Integer b = bFutureTask.get();
            Integer c = cFutureTask.get();
            res = a + b + c;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            threadPoolExecutor.shutdown();//关闭线程池
        }
        long times = System.currentTimeMillis() - strat;
        log.info("所花时间:{}",times);
        return res;
    }

    public static Integer add(String flag,String str){
        System.out.println(str);
        int res = 0;
        if("a".equals(flag)){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }
        else if("b".equals(flag)){
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 2;
        }else {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    public static void main(String[] args) {
        Integer test = ThreadUtils.someThreado("Test");
        System.out.println("结果======"+test);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值