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

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()执行完成的时候。

4G和智能组网一次搞定,蒲公英X4C路由器分享随着互联网时代的发展,相信大家现在对路由器已经非常熟悉了吧?今天开箱的产品是蒲公英X4C路由器,这可不是单纯支持无线上网的普通路由器喔,不到200元的价格,却买到了一款支持4G和智realmeC35将在泰国推出网友入门手机都这么好看?手机中国新闻近几年,realme不仅在国内迎来了快速发展,在海外也取得了不错的市场份额。2月8日,realme海外官方确认,将于2月10日在泰国推出realmeC35手机。该机是r山寨App套路多随着移动互联网技术的快速发展和应用普及,各类App渗入人们生活的方方面面,与此同时各种山寨App也浮出水面,如大量虚假的贷款App并无真实贷款业务,仅用于诈骗分子骗取用户的钱财和隐谷歌效仿巴菲特脸书致敬谷歌赌登月计划赌元宇宙谷歌改名一分为二2015年,谷歌宣布更名为Alphabet,意图向市场表明,该公司不仅仅是一家广告公司。投资者为此感到兴奋,改名后谷歌股价上涨4。谷歌管理层表示,这是效仿巴菲特的伯记者卧底10多个网络水军群发现网购一致好评可能是刷出来的今年年初,国家互联网信息办公室发布关于移动互联网应用程序信息服务管理规定(征求意见稿)公开征求意见的通知。征求意见稿规定,应用程序提供者应当规范经营管理行为,不得通过机器或人工方式掌趣科技旗下玩蟹科技现充值漏洞,玩家白嫖游戏商品赚钱,获利190万被判5年金融界2月9日消息数字时代,互联网信息犯罪日益高发,近期,一起利用系统漏洞牟利的案件引发关注。根据北京法院的刑事判决书,北京玩蟹科技有限公司(以下简称蟹玩科技)成为了受害者。天眼查又一颗中国5G芯片将问世日前,翱捷科技5G基带通信芯片已经流片成功,正在推进量产测试等工作,预计今年能实现量产。那么,5G芯片将有华为海思,紫光展锐,翱捷科技这几个国产厂商。海思不用说了,由于某种原因还停中概股组团上涨,发生了什么?中新经纬2月9日电中概股组团上涨,发生了什么?周二美股收盘,热门中概股多数上涨。新能源汽车股集体上涨,蔚来汽车涨2。96,小鹏汽车涨0。81,理想汽车涨1。29。科技股拼多多涨12软银停止出售芯片设计公司ARM,孙正义公司经历的暴风雪越来越猛美国时间周二,最新公布的企业财报提振了市场信心,美国三大股指集体上涨。截至收盘,标普500指数上涨0。84,道指上涨1。06,纳指涨幅为1。28。最新出炉企业财报提振市场信心8日美比亚迪投了一家福建的光伏公司虎年伊始,比亚迪又一笔投资浮出水面。投资界获悉,太阳能电池生产设备提供商福建金石能源有限公司(简称金石能源)近日完成一轮战略融资,新增包括比亚迪汇金创投厦门国兴投资等在内的6家股东国内首份人脸信息处理合规操作指南发布随着个人信息保护相关法律法规的稳步推进,合规处理要求日益紧迫。为帮助人脸信息处理者落实法律法规的相关要求,中国信息通信研究院云计算与大数据研究所联合相关机构和专家,依托可信人脸应用
关于助听器的佩戴与认知知识有什么?你好,助听器初始佩戴时间由短慢慢增长,环境由安静的逐渐到嘈杂的,听觉分为两部分,听见和听清楚,助听器可以帮助听损的人听的见,听的清,听的懂就要看自身的言语分辨能力如何,再好的助听器要管理好小孩用的电子产品第一块电话手表2018年暑假,为了联系方便,给正在读小学的神兽买了一块电话手表,当时入手的这一块手表价格300元左右,配置参数2G网络,前摄像头30万像素,电池600mAh,待机状OPPOReno7预计起售价3000元,Reno6超低价在眼前,网友欢呼又有一款新机即将发布,这款新机就是OPPOReno7系列,根据爆料信息来看,OPPOReno7预计10月份闪亮登场。OPPOReno7预计正面采取了6。6英寸OLED材质的挖孔直面全力为iPhone13让路,iPhone12mini已跌破4000元,且买且珍惜一直以来,小屏手机都以优越的便携性获得了不少消费者的青睐。为了满足小屏党们的期待,苹果在去年秋季新品发布会上,正式发布全球首款最轻最小的5G手机iPhone12mini,起售价为5为啥没人开发特斯拉新能源三轮车?中国己经步入老龄社会,老年人工作了一辈子,操劳了一辈子,如今大部分人都己退休或将要退休,回家后,接孙子做家务之余,也想四处去转转,散散心,到处去旅游一下。坐火车虽然省心,但自由度差a16z为美国政府提议去中心化友好的监督制度链得得(微信号ChainDD)10月06日讯,据CoinDesk报道,风险投资公司AndreessenHorowitz(a16z)提出了美国政府可以管理加密货币和区块链技术的四个主以制度设计应对智能时代主体性危机自18世纪蒸汽机的发明开始,历次工业革命催生了电力化信息通讯技术以及人工智能的发展,每一次技术更迭都会引发人们对就业市场的忧思。工业化进程带来了人口的迁徙和身份的转变,人工智能作为未来在移动芯片移动操作系统方面诞生的操作系统将层出不穷马云认为1。老板和所有的高层一定要想明白,要有未来观,从未来看今天。2。要有全球观,从全球未来看今天。3。全局观,讲政治是全局观很重要的一部分。这是公司高层管理必须要有的三观。未来车企开始突破新能源赛道极点随着上市公司年中报披露落下帷幕,各大车企也悉数交出了期中考的成绩单。透过纷繁复杂的数据不难发现,新能源这个元素似乎成了提分宝典,大多车企都把新能源汽车领域的单科成绩放在半年报的显著一农民工自封互联网先知并扬言要做后互联网时代最大公司拚搏人生,无限精彩,一要努力,二靠平台。平台的维度高低关乎事业的格局大小。不怕牛皮吹得大,一旦实现皆神话。早已没人质疑马云当年夸下的海口,阿里就在那儿。全球云公司,既然出自谁口都像斯诺登发声脸书宕机事件俄罗斯卫星通讯社莫斯科10月4日电,前美国中央情报局官员爱德华斯诺登表示,脸书的大范围故障的结果是让世界变得更健康。周一,世界各地的脸书Instagram和WhatsApp用户报告