请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?

[复制链接]
查看: 52|回复: 0

1万

主题

2万

帖子

4万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
47993
发表于 2019-12-4 01:35 | 显示全部楼层 |阅读模式
前言

上文我们先容了JDK中的线程池框架Executor。我们晓得,只要需要建立线程的情况下,即使是在单线程形式下,我们也要尽管操纵Executor。即:
  1. ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1); //此处不应操纵Executors工具类来初始化线程池
复制代码
可是,在《阿里巴巴Java斥地手册》中有一条
【逼迫】线程池不答应操纵 Executors 去建立,而是经过 ThreadPoolExecutor 的方式,这样的处置赏罚方式让写的同学加倍大白线程池的运转法则,躲避资本耗尽的风险。
Executors 返回的线程池工具的弊端以下:
FixedThreadPool 和 SingleThreadPool : 答应的请求行列长度为 Integer.MAX_VALUE,大要会聚积大量的请求,从而致使 OOM。
CachedThreadPool 和 ScheduledThreadPool : 答应的建立线程数目为 Integer.MAX_VALUE,大要会建立大量的线程,从而致使 OOM。
可以看到,这是一个逼迫性的法则,而且是不答应操纵Executors来建立,倡议操纵ThreadPoolExecutor来建立线程池,那我们先往返顾一下Executors和ThreadPoolExecutor。
【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?  游戏 1110433-20191203221924524-1813120063

我们可以看到ThreadPoolExecutor已经是Executor的具体实现了,而且具有较多可配参数(可配参数见下方,可仅了解,用到时再举行具体查询)。Executors是一个建立线程池的工具类,检察其源码的话也会发现这几种建立线程池的方式也都是经过挪用ThreadPoolExecutor来实现的。
ThreadPoolExecutor一共有四个机关函数,七个可配参数,别离是

  • corePoolSize: 线程池中连结存活线程的数目。
  • maximumPoolSize: 线程池中答应线程数目标最大值
  • keepAliveTime: 表示线程没有使命尝试时最多连结多久时候会停止
  • unit: 参数keepAliveTime的时候单元
  • workQueue: 一个阻塞行列,用来存储等待尝试的使命
  • threadFactory: 线程工场,严重用来建立线程
  • handler:表示当拒绝处置赏罚使命时的计谋
分析

那末Executors到底会致使什么题目,才会让斥地手册中间接被界说为不答应了呢。首先就是一个血淋淋的教导,间接致使线上办事不成用,已经可以算是事变了。
尝试

我们也可以现在我们当地举行一下小尝试:
  1. public class ExecutorsTesting {    private static ExecutorService executor = Executors.newFixedThreadPool(15);    public static void main(String[] args) {        for (int i = 0; i < Integer.MAX_VALUE; i++) {            executor.execute(new SubThread());        }    }}class SubThread implements Runnable {    @Override    public void run() {        try {            Thread.sleep(10000);        } catch (InterruptedException e) {            //do nothing        }    }}
复制代码
运转时指定JVM参数:-Xmx8m -Xms8m,大要几秒钟以后,会报出OOM毛病:
  1. Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded    at com.kaikeba.mybatis.ExecutorsTesting.main(ExecutorsTesting.java:10)     //报错行数为上述代码中的executor.execute(new SubThread());
复制代码
那末为什么会报出这个毛病呢。
源码分析

我们先来看一下Executors中的FixedThreadPool是怎样机关的。
  1. public static ExecutorService newFixedThreadPool(int nThreads) {    return new ThreadPoolExecutor(nThreads, nThreads,                                  0L, TimeUnit.MILLISECONDS,                                  new LinkedBlockingQueue());}
复制代码
可以看到对于存储等待尝试的使命,FixedThreadPool是经过LinkedBlockingQueue来实现的。而我们晓得LinkedBlockingQueue是一个链表实现的阻塞行列,而假如不设备其容量的话,将会是一个无界限的阻塞行列,最大长度为Integer.MAX_VALUE。由于Executors中并未设备容量,所以利用可以不停向行列中增加使命,致使OOM毛病
上面提到的题目严重表现在newFixedThreadPool和newSingleThreadExecutor两个工场方式上,并不是说newCachedThreadPool和newScheduledThreadPool这两个方式就平安了,这两种方式建立的最大线程数大如果Integer.MAX_VALUE,而建立这么多线程,一定就有大要致使OOM。
怎样该操纵ThreadPoolExecutor来建立线程池呢?
我们实在可以看到Executors中的newFixedThreadPool实在也是挪用ThreadPoolExecutor来实现的。正如手册中所说,当我们不用Executors默许建立线程池的方式,而间接自己手动去挪用ThreadPoolExecutor,可以让写的同学加倍大白线程池的运转法则,躲避资本耗尽的风险。比如我们在Executors.newFixedThreadPool根柢上给LinkedBlockingQueue加一个容量,当行列已经满了,而仍需要增加新的请求会抛出响应很是,我们可以按照很是做响应处置赏罚。
  1. public static ExecutorService newFixedThreadPool(int nThreads) {    return new ThreadPoolExecutor(nThreads, nThreads,                                  0L, TimeUnit.MILLISECONDS,                                  new LinkedBlockingQueue(10)); //增加容量巨细}
复制代码
除了自己界说ThreadPoolExecutor外。还可以操纵此外开源类库,如apache和guava等,可以有更多本性化设备。
参考文章:
https://www.hollischuang.com/archives/2888
https://stackoverflow.com/questions/1094867/when-should-we-use-javas-thread-over-executor#answer-34373289
https://blog.51cto.com/zero01/2306857
本文由博客一文多发平台 OpenWrite 公布!
文章首发:https://zhuanlan.zhihu.com/lovebell
小我公众号:技术Go
您的点赞与支持是作者连续更新的最大动力!

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 妈妈网-中国妈妈第一,是怀孕、育儿、健康等知识交流传播首选平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表