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

  • 相关阅读:
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    8.4 确定两个日期之间的月份数或年数
    (Java实现) 洛谷 P1553 数字反转(升级版)
  • 原文地址:https://www.cnblogs.com/ushowtime/p/12502797.html
Copyright © 2011-2022 走看看