范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

ThreadPoolExecutor的核心参数以及线程池状态到底是咋玩的?

  如果下面的问题你都会的话就别在这浪费时间啦线程池的参数有哪些?分别代表啥意思? 线程池是怎么创建线程的? 任务拒绝策略有哪些? 线程池的状态都有哪些?怎么存储的?怎么计算的(如何获取到的状态变量?如何获取到的线程数?)? 为什么用-1来表示运行中RUNNING状态? new一个线程池,他的活跃线程数是多少?怎么计算的?
  PS:像线程池流程源码、核心非核心线程怎么保证一直存活等等问题后面会讲解,此篇幅核心是线程池状态的那个位运算到底是咋玩的。 1、线程池参数1.1、线程池参数有哪些?都啥意思? public ThreadPoolExecutor(int corePoolSize,                            int maximumPoolSize,                            long keepAliveTime,                            TimeUnit unit,                            BlockingQueue workQueue,                            ThreadFactory threadFactory,                            RejectedExecutionHandler handler) {  }corePoolSize :核心线程数
  线程池在完成初始化之后,默认情况下,线程池中不会有任何线程,线程池会等有任务来的时候再去创建线程,核心线程创建出来后即使超出了线程保持的存活时间配置也不会销毁,核心线程只要创建了就永驻了,就等着新任务来进行处理。 除非设置了allowCoreThreadTimeOut,否则核心线程数是保持活动的最小数量0 maximumPoolSize :最大线程数
  核心线程忙不过来且任务队列都满了的情况下,还有新任务继续提交进来的话就会新开辟线程,但是也不会任意的开辟线程数量,线程数(包含核心线程数)阈值是 maximumPoolSize ,达到阈值后还在提交任务的话就走拒绝策略。keepAliveTime :非核心线程保持存活的时间
  如果线程池当前的线程数多于 corePoolSize ,那么如果多余的线程空闲之间超出keepAliveTime 的话,则这些线程就会被回收。unit :非核心线程保持存活的时间单位
  比如: TimeUnit.MILLISECONDS 、TimeUnit.SECONDS workQueue :任务存储队列核心线程数满了后还在继续提交任务到线程池的话,就先进入 workQueue ,workQueue 通常有以下几种选择:
  LinkedBlockingQueue :无界队列,默认长度限制是int的最大值。也可以自定义大小。
  ArrayBlockingQueue :有界队列,可以自定义大小。
  SynchronousQueue :Executors.newCachedThreadPool(); 默认使用的队列。也不算是个队列,他不没有存储元素的能力。
  一般我都采取 LinkedBlockingQueue ,因为他也可以设置大小,可以取代ArrayBlockingQueue 有界队列。threadFactory :当线程池需要新的线程时,会用threadFactory 来生成新的线程。
  默认采用的是 DefaultThreadFactory ,主要负责创建线程。newThread() 方法。创建出来的线程都在同一个线程组里且优先级是一样的。handler :拒绝策略。任务超出线程池的配置限制后或执行shutdown后还在继续提交任务的话,会执行handler 里的逻辑。
  默认采取的是 AbortPolicy 拒绝策略。也就是直接抛出RejectedExecutionException 异常。1.2、线程池是怎么创建线程的?
  是通过 java.util.concurrent.ThreadFactory#newThread 来负责创建的,ThreadFactory是个接口,比如有个Default实现io.netty.util.concurrent.DefaultThreadFactory#newThread(java.lang.Runnable)  public Thread newThread(Runnable r) {      Thread t = this.newThread(FastThreadLocalRunnable.wrap(r), this.prefix + this.nextId.incrementAndGet());         try {          if (t.isDaemon() != this.daemon) {              t.setDaemon(this.daemon);          }             if (t.getPriority() != this.priority) {              t.setPriority(this.priority);          }      } catch (Exception var4) {          ;      }         return t;  }
  可以看到如下信息: 就是个线程工厂类一样,负责创建线程,创建的方式也是直接new Thread 并没有真正的启动,也就是没有调用start方法,只是new出来了而已,也就是说new一个线程池并没有启动线程
  真正启动线程是在来任务的时候启动的,之后文章会深度剖析。 线程优先级以及是否是守护线程都是可以配置 1.3、任务拒绝策略有哪些?
  顶层父接口是 java.util.concurrent.RejectedExecutionHandler ,其四大子类如下:AbortPolicy :抛出一个RejectedExecutionException异常,默认的拒绝策略public static class AbortPolicy implements RejectedExecutionHandler {     public AbortPolicy() {}     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {         throw new RejectedExecutionException("Task " + r.toString() +                                              " rejected from " +                                              e.toString());     } }DiscardPolicy:直接丢弃任务,源码很简单,我不做任何处理,其实就是丢弃嘛 public static class DiscardPolicy implements RejectedExecutionHandler {      public DiscardPolicy() { }      public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {      }  }DiscardOldestPolicy :丢弃队列里最老的任务(直接从queue中弹出最前面的一个任务),将当前这个任务继续提交给线程池 public static class DiscardOldestPolicy implements RejectedExecutionHandler {      public DiscardOldestPolicy() { }      public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {          if (!e.isShutdown()) {              e.getQueue().poll();              e.execute(r);          }      }  }CallerRunsPolicy :交给线程池调用所在的线程进行处理。也就是说不允许丢任何任务,一般用于不允许失败的、对性能要求不高、并发量较小的场景下使用,因为提交的任务一定会被运行,但是由于是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能和效率自然就慢了。 public static class CallerRunsPolicy implements RejectedExecutionHandler {      public CallerRunsPolicy() { }      public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {          if (!e.isShutdown()) {              r.run();          }      }  }1.4、线程池的原理是什么?线程池刚启动的时候核心线程数为0。 丢任务给线程池的时候线程池会开启线程来执行这个任务。 若线程数小于 corePoolSize 的话,即使工作线程处于空闲状态,也会创建一个新线程来执行任务。若线程数大于等于 corePoolSize 的话,则会将任务放到workQueue ,也就是任务队列。若任务队列满了,且线程数小于 maximumPoolSize ,则会创建一个新线程来运行任务。若任务队列满了,且线程数大于等于 maximumPoolSize ,则会直接采取拒绝策略。
  线程池工作原理.png
  PS:源码会在之后的文章深度剖析。 2、线程池的状态2.1、线程池有哪几种状态?
  如下五种:  private static final int RUNNING    = -1 << COUNT_BITS;  private static final int SHUTDOWN   =  0 << COUNT_BITS;  private static final int STOP       =  1 << COUNT_BITS;  private static final int TIDYING    =  2 << COUNT_BITS;  private static final int TERMINATED =  3 << COUNT_BITS;RUNNING:接收新任务和线程池队列中的任务 SHUTDOWN:不接受新任务,但是接收线程池队列中的任务 STOP:不接收新任务也不接收线程池队列中的任务,并且打断正在进行中的任务 TIDYING:所有任务终止,待处理任务数量为0的时候,线程转换为TIDYING状态,将会执行terminated钩子函数 TERMINATED:terminated函数执行完成后会变为此状态 2.2、线程池的状态是怎么存储的?
  采取一个int类型名叫ctl的变量来存储。低29位存储线程池中线程的活跃数量,高3位存储线程池的状态。
  如下源码:  private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));  // 29  private static final int COUNT_BITS = Integer.SIZE - 3;  // 线程池容量  private static final int CAPACITY   = (1 << COUNT_BITS) - 1;     // 线程池状态,只有RUNNING状态是负数。  private static final int RUNNING    = -1 << COUNT_BITS;  private static final int SHUTDOWN   =  0 << COUNT_BITS;  private static final int STOP       =  1 << COUNT_BITS;  private static final int TIDYING    =  2 << COUNT_BITS;  private static final int TERMINATED =  3 << COUNT_BITS;
  为啥这么设计?因为作者是Doug Lea,当然是节省空间,如果弄一个int存储线程数,一个int存储仅需要3位的状态,那浪费太多空间了。即使用byte存储状态,也浪费了五个bit空间。想想读写锁的设计,也是出自Doug Lea之手。比如:
  线程池状态存储.png 2.3、线程池的状态是怎么计算的? private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));     // 线程池状态,只有RUNNING状态是负数。  private static final int RUNNING    = -1 << COUNT_BITS;  private static final int SHUTDOWN   =  0 << COUNT_BITS;  private static final int STOP       =  1 << COUNT_BITS;  private static final int TIDYING    =  2 << COUNT_BITS;  private static final int TERMINATED =  3 << COUNT_BITS;
  我们知道在java中 int 类型占用4个字节32位存储, 上述的几种状态:底层存储二进制为:  1111 1111 1111 1111 1111 1111 1111 1111(-1)  0000 0000 0000 0000 0000 0000 0000 0000(0)  0000 0000 0000 0000 0000 0000 0000 0001(1)  0000 0000 0000 0000 0000 0000 0000 0010(2)  0000 0000 0000 0000 0000 0000 0000 0011(3)
  左移<【SHUTDOWN】:调用shutdown()方法。 【RUNNING/SHUTDOWN】->【STOP】:调用shutdownNow()方法。 【SHUTDOWN】->【TIDYING】:队列和线程池都是空的。也就是说shutdown()后任务都执行完毕的时候会变成TIDYING。 【STOP】->【TIDYING】:线程池为空。也就是说执行shutdownNow()方法后,所有线程都停止后状态会变为TIDYING。 【TIDYING】->【TERMINATED】:钩子函数terminated()执行完成的时候。

美元霸权祸乱世界金融风暴愈演愈烈四国重磅出手!打响汇率保卫战当前美元之强历史罕见,美元指数创20年以来的新高。与之对应的是,全球非美货币普遍疲软,货币贬值成为困扰各国的重大问题。英镑对美元,日元兑美元,欧元兑美元,均在近期继续创出了新低。受重磅发声!一则传言搅动A股,接近监管相关人士消息不实中国基金报记者李树超一则传言搅动市场,监管和行业机构快速辟谣。记者从接近监管层的相关人士处获悉,9月27日,相关媒体关于经纪商和基金经理接受监管指导的报道属不实信息,监管层近期未对外国投资者持续看好中国市场来源人民网人民日报海外版位于江苏如皋经济技术开发区的威格(江苏)电气设备有限公司是一家主要生产低压以及中高压电机的外资企业。近年来,公司通过不断加大研发投入,进行自动化智能化改造,又一个千万人口大城诞生了!会改变南北格局吗?文刘博团队刚刚,山东官宣,省会济南实有人口破千万。在9月27日举行的山东这十年济南主题新闻发布会上,济南市委书记透露了一个重要数据济南实有人口突破1000万。这对济南来讲,是一个历上海出台新一轮稳增长政策,22条重点帮扶这些行业在3月底和5月底先后出台抗疫助企21条经济恢复重振50条两轮政策后,上海再发22条政策助企纾困。9月28日,上海市助行业强主体稳增长的若干政策措施(下称22条)公布,从四个方面巩固危机升级!人民币汇率突发大贬值?央妈喊话震慑?如何解读?人民币汇率到底怎么了?最近几天,人民币汇率突发大贬值,短短几个交易日,人民币兑美元汇率接连突破数个关口,并于今天跌破7。2,创下了20年以来的新低。人民币汇率出现贬值,跌破7。20李克强主持召开国务院常务会议李克强主持召开国务院常务会议决定对部分行政事业性收费和保证金实行阶段性缓缴进一步帮助市场主体减负纾困部署推进政务服务跨省通办扩面增效举措激发市场活力便利群众生活部署抓好秋粮收获和加韩国金融委员会将重新启动股票稳定基金韩国金融委员会9月28日表示,为了稳定金融市场,将准备重新启动股票稳定基金。韩国金融委员会当天与金融监督院一起召开了金融市场联合检查会议,重新检查了股市等金融市场现状,并表示将及时养老保险缴费15年,选择最低档次,可以领取多少养老金?计算你看按照最低档次缴纳养老保险,缴费15年,可以领取到多少养老金?计算你看缴费年限15年,一直按照最低档次缴纳的养老保险,这样的参保条件下,拿到的养老金也是比较低的,一般来说,如果参与的我们悄悄与落叶告别作者郭继明秋天里那些经历寒凉的枯叶坚强的展现出生命的最后之美带着消失和破碎的痛苦仍放射出金黄和橙色的光落在小径上的烙着岁月的影子用五颜六色给人以视觉上的震撼安然的叶子躺在一幅水墨画舍得,舍就是得舍得舍得,有舍才有得。不过很多人却总是弄错顺序,想先得而后舍。这样做,不仅很难得到自己想要的,往往还会让自己陷入烦恼。他们不知道,舍不是弃不是丢掉,而是得的前提,是获得的先决条件,
我在赵家沟等你(散文)赵家沟的慢生活之十一摘要离家四十年的我,回到赵家沟,筑成竹韵书院。黄昏时分,沾满一身的夕阳的我,在幽静的老宅里,阅读写作,丝毫不寂寞,有鸟儿作伴,有朋友支持,我们一起将书院做大做强,开启智慧之窗,让文独坐窗前自笔耕人生于世,白驹过隙转身一瞬,便是永恒!既然如此,在屈指可数的人生里,不管是什么人,无论处在什么状况,都要有自知之明,千万不要刚愎自用,自以为是不要固执己见,执迷不悟不要看这个不顺眼手机曲面屏与直面屏哪个贵?自三星开创了手机曲面屏的先河,国内厂商纷纷效仿,现在几乎找不到直面屏的国内品牌的旗舰机型,只有中低端的机型采用直面屏了。然而现在的三星手机曲面屏做得越来越不曲了,都叫微曲了,可能是家庭电视选购有技巧!注意避开3个大坑,家里人都夸选得好随着科技的不断发展,各种电器的更新迭代也越来越快。就拿电视来说,选购时导购嘴里的各种科技名词让人云里雾里,很多朋友被绕了一大圈,花大价钱捧回家一个不合适的电视机,但是后悔也已经晚了梦碎了!李嘉诚3000亿资产重新分配,梁洛施和三个儿子一分钱没有李嘉诚正式退休,全部资产重新分配,李泽楷和梁洛施的孩子一分没有引言。自从李嘉诚宣布退休之后,不少网友都惦记着想知道他家财产如何分配。毕竟这些年在各大香港媒体的报道中,也对李嘉诚资产北京银行个人医保存折客户已打入医保存折资金仍可支取今日,北京市医保局印发关于调整本市城镇职工基本医疗保险有关政策的通知(京医保发202228号),政策中明确自2022年9月1日起,个人账户资金实行记账管理,参保人员不可自由支取,实诺基亚强势回归,新诺基亚N76概念图曝光,还有人买吗?声明原创不易,禁止搬运,违者必究!手机在发展的过程中,也发生翻天覆地的变化。曾经在手机市场,诺基亚称得上真正的赢家,占据极大的市场份额,那时候可以说是人手一部诺基亚手机,市场地位丝颠覆传统笔记本,高圆圆钟爱的华为小镁本到底有多好看?不知道大家有没有发现,近两年电子产品在外观上的革新可谓是层出不穷,以手机为例,每年都能诞生出不少优秀的外观设计ID,从素皮再到陶瓷机身,满足了更多用户对手机外观个性的诉求。在笔记本别再说国产相机造不出来了!新一代国产8K摄像机已经来了常常看到有网友说,我们没有国产相机。事实上,这是一个误解。我们有国产相机,只是在终端消费领域还需要多点努力。而有这么一家企业,做望远镜20多年,有着丰富的光学技术经验。2018年,三星GalaxyZFold4折叠手机耐用度高,高效生产力备受关注的三星GalaxyZFold4折叠屏手机现在已经正式亮相,很多用户都非常喜欢这款手机。而这款手机在设计,影像以及生产力上面有很大的提升,让我们能够得到更好的体验。同时可以更新机2970元起!联想拯救者Y70发布ZUI14发布会不用看,最新资讯只看数码科技。最详细最准确(图源水印侵删)就在昨天联想拯救者发布会几款新品分别是联想拯救者Y70联想小新padpro2022行李箱降噪耳机E5小新魔豆等等处理