• 手动实现线程池 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

  • 相关阅读:
    装箱与拆箱
    java中final的用法
    一次坑爹的Oracle in查询
    Spring-Security-Oauth整合Spring-Security,拦截器
    jvisualvm连接远程Tomcat
    7.Spring-Cloud服务容错保护之Hystrix初探
    8.Spring-Cloud-Hystrix之异常处理
    9.Spring-Cloud-Hystrix之请求缓存(踩坑)
    10.Spring-Cloud-Hystrix之熔断监控Hystrix Dashboard单个应用
    11.Spring-Cloud-Hystrix之熔断监控Turbine
  • 原文地址:https://www.cnblogs.com/ushowtime/p/12502797.html
Copyright © 2020-2023  润新知