zoukankan      html  css  js  c++  java
  • 手动实现线程池 ThreadPool

    Executors提供了三个经典的线程池创建方式

    ExecutorService threadPool = Executors.newFixedThreadPool(int)

    ExecutorService threadPool = Executors.newSingleThreadPool()
    ExecutorService threadPool = Executors.newCachedThreadPool(int)

    那我们在工作中到底用哪一个呢?

    答案是我们在生产上只能用自定义的

    根据图中我们可以发现他们得底层实现都是用了ThreadPoolExecutor,然而第五个参数使用到的阻塞队列默认值是Integer.MAX_VALUE,也就是

    2147483647,这样就相当于是一个无界的队列。所有的请求都往里塞,最终造成OOM。

    根据阿里编码规范也可以看出

    参数说明

    线程池底层实现的7大参数
    1.corePoolSize:线程池中的常驻核心线程数
    2.maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1
    3.keepAliveTime:多余的空闲线程的存活时间
    4.unit:keepAliveTime的单位
    5.workQueue:任务队列,被提交但尚未被执行的任务。
    6.threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认
    7.handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数

    工作原理

    线程池的底层工作原理
    core基本线程数,当线程数大于corePoolSize时,多余线程将转入阻塞队列,阻塞队列也满了之后
    将扩容到maximumPoolSize数。maximumPoolSize也满了之后将采取拒绝策略。
    当线程数小了之后,根据设定的空闲线程存活时间将线程总容量回缩到corePoolSize

    手动实现

    /**
    * 线程池demo
    * @author t
    * 实际工作中对多线程的使用都是线程池,不会显示的创建线程
    * 而使用传统方式的方法创建线程池容易造成oom
    */
    public class ThreadPoolDemo {
        public static void main(String[] args) {
            ExecutorService threadPool = new ThreadPoolExecutor(
                    2,
                    5,
                    1,
                    TimeUnit.SECONDS,
                    new LinkedBlockingDeque<>(3),
                    Executors.defaultThreadFactory(),
                    new ThreadPoolExecutor.AbortPolicy());
            try {
                for (int i = 1; i <= 10; i++) {
                    final int num = i;
                    threadPool.execute(() -> {
                        //打印当前线程名称
                        //暂停一会线程
                        System.out.println("序号 "+num+"  "+Thread.currentThread().getName()+" 办理业务");
                    });
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                threadPool.shutdown();
            }
        }
    }

    运行结果

    注意:根据机器配置不同运行效果也不同,本来应该是超过最大线程数(maximumPoolSize+队列大小)就会触发拒绝策略,但是由于机器处理速度

    能够处理的过来,所以没有报错。

    线程暂停1秒,9个线程的运行结果

    作者:ushowtime

    原文地址:https://www.ushowtime.cn/blog/p/50

  • 相关阅读:
    携程的 Dubbo 之路
    应用上云新模式,Aliware 全家桶亮相杭州云栖大会
    重构:改善饿了么交易系统的设计思路
    Arthas 3.1.2 版本发布 | 增加 logger/heapdump/vmoption 命令
    如何检测 Web 服务请求丢失问题
    VPGAME的Kubernetes迁移实践
    Flink SQL 系列 | 5 个 TableEnvironment 我该用哪个?
    如何构建批流一体数据融合平台的一致性语义保证?
    Flink on YARN(下):常见问题与排查思路
    愚蠢的操作
  • 原文地址:https://www.cnblogs.com/ushowtime/p/12502797.html
Copyright © 2011-2022 走看看