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

深入理解Java线程池,这一篇就够了

  【死记硬背】 1 理解
  线程是稀缺资源,它的创建和销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需要进行操作系统状态切换,为避免资源过度消耗需要设法重用线程执行多个任务。线程池就是一个线程缓存,负责对线程进行统一分配、调度和监控。2 线程池的作用
  * 限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃。
  * 线程池不需要每次都去创建和销毁,节约了资源,并且响应速度快。3 什么时候用线程池
  * 单个任务处理的时间比较短。
  * 需要处理的任务数量很大。4 如何设置线程池的大小
  * CPU密集型任务:
  CPU个数+1的线程数
  * IO密集型任务:
  两倍CPU个数+1的线程数5 线程池的组成
  一般的线程池主要由4部分组成:
  5.1 线程池管理器:用于创建并管理线程池。
  5.2 工作线程:线程池中的线程。
  5.3 任务接口:每个任务必须实现的接口,用于工作线程调度其运行。
  5.4 任务队列:用于存放待处理的任务,提供一种缓冲机制。6 线程池的实现方式
  线程池的主要实现方式有五种:newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor和newWorkStealingPool。是通过Executor框架实现的,主要用到了Executor、Executors、ExecutorService、ThreadPoolExecutor、Callable、Future和FutureTask这几个类。7 线程池涉及到的主要参数
  7.1 corePoolSize:指定了线程池中的线程数量。
  7.2 maximumPoolSize:指定了线程池中最大线程数量。
  7.3 keepAliveTime:当前线程池数量超过corePoolSize时,多余的空闲线程的存活时间,即多少时间内会被销毁。
  7.4 unit:keepAliveTime的时间单位。
  7.5 workQueue:任务队列,被提交但尚未被执行的任务。
  7.6 threadFactory:线程工厂,用于创建线程,一般用默认的即可。
  7.7 handler:拒绝策略,当任务太多来不及处理,如何拒绝任务。8 拒绝策略
  JDK内置的拒绝策略如下:
  8.1 AbortPolicy:直接抛出异常,阻止系统正常运行。
  8.2 CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
  8.3 DiscardOldestPolicy:丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
  8.4 DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢失,这是最好的一种方案。
  以上内置拒绝策略均实现了RejectedExecutionHandler接口,若以上策略扔无法满足实际需要,完全可以自己扩展RejectedExecutionHandler接口。9 Java线程池的工作过程
  9.1 线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。
  9.2 当调用 execute() 方法添加一个任务时,线程池会做如下判断:
  a) 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
  b) 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
  c) 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
  d) 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池
  会抛出异常 RejectExecutionException。
  9.3 当一个线程完成任务时,它会从队列中取下一个任务来执行。
  9.4 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
  【答案解析】
  五种常用线程池的实现方式:newCachedThreadPoolimport java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;  /**  * 它是一个可以无限扩大的线程池;  * 它比较适合处理执行时间比较小的任务;  * corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;  * keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;  * 采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,  * 就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。  */ public class CachedThreadPoolTest {     public static void main(String[] args) {         ExecutorService cachedThreadPool = Executors.newCachedThreadPool();         for (int i=0;i<1000;i++){             /*try{                 Thread.sleep(2000);             }catch (InterruptedException e){                 e.printStackTrace();             }*/             cachedThreadPool.execute(new Runnable() {                 @Override                 public void run() {                     System.out.println(Thread.currentThread().getName()+"正在被执行");                 }             });             System.out.println("执行完毕");         }      } }newFixedThreadPoolimport java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;  /**  * 它是一种固定大小的线程池;  * corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;  * keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉;  * 但这里keepAliveTime无效;  * 阻塞队列采用了LinkedBlockingQueue,它是一个无界队列;  * 由于阻塞队列是一个无界队列,因此永远不可能拒绝任务;  * 由于采用了无界队列,实际线程数量将永远维持在nThreads,因此maximumPoolSize和keepAliveTime将无效  */ public class FixedThreadPoolTest {     public static void main(String[] args) {         ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);         for (int i=0;i<10;i++){             final int index = i;             fixedThreadPool.execute(new Runnable() {                 @Override                 public void run() {                     try{                         System.out.println(Thread.currentThread().getName()+"正在执行"+index);                         Thread.sleep(2000);                     }catch (InterruptedException e){                         e.printStackTrace();                     }                 }             });         }     } }newScheduledThreadPoolimport java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit;  /**  * 它接收SchduledFutureTask类型的任务,有两种提交任务的方式:  * 1 scheduledAtFixedRate  * 2 scheduledWithFixedDelay  * SchduledFutureTask接收的参数:  * time:任务开始的时间  * sequenceNumber:任务的序号  * period:任务执行的时间间隔  * 它采用DelayQueue存储等待的任务  * DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;  * DelayQueue也是一个无界队列;  * 工作线程的执行过程:  * 工作线程会从DelayQueue取已经到期的任务去执行;  * 执行结束后重新设置任务的到期时间,再次放回DelayQueue  */ public class ScheduledThreadPoolTest {     public static void main(String[] args) {         ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);         /**/         scheduledThreadPool.schedule(new Runnable(){             public void run(){                 System.out.println("延迟1秒执行");             }         }, 1, TimeUnit.SECONDS);         scheduledThreadPool.scheduleWithFixedDelay(new Runnable() {             @Override             public void run() {                 System.out.println("执行");             }         },1,1,TimeUnit.SECONDS);         scheduledThreadPool.scheduleAtFixedRate(new Runnable() {             @Override             public void run() {                 System.out.println("执行3");             }         },1,3,TimeUnit.SECONDS);     } }newSingleThreadExecutorimport java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;  /**  * 它只会创建一条工作线程处理任务;  * 采用的阻塞队列为LinkedBlockingQueue;  */ public class SingleThreadExecutorTest {     public static void main(String[] args) {         ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();         for (int i = 0; i < 10; i++) {             final int index = i;             singleThreadExecutor.execute(new Runnable() {                 public void run() {                     try {                         System.out.println(Thread.currentThread().getName() + "正在被执行,打印的值是:" + index);                         Thread.sleep(1000);                     } catch (InterruptedException e) {                         e.printStackTrace();                     }                 }             });         }     } }newWorkStealingPoolimport java.util.concurrent.*; public class WorkStealingPoolTest {     // 线程数     private static final int threads = 10;     // 用于计数线程是否执行完成     static CountDownLatch countDownLatch = new CountDownLatch(threads);      public static void main(String[] args) throws Exception{         test3();     }      public static void test1() throws Exception{         System.out.println("---- start ----");         ExecutorService executorService = Executors.newWorkStealingPool();         for (int i = 0; i < threads; i++) {             executorService.execute(() -> {                 try {                     System.out.println(Thread.currentThread().getName());                 } catch (Exception e) {                     System.out.println(e);                 } finally {                     countDownLatch.countDown();                 }             });         }         countDownLatch.await();         System.out.println("---- end ----");     }      public static void test2() throws InterruptedException{         System.out.println("---- start ----");         ExecutorService executorService = Executors.newWorkStealingPool();         for (int i = 0; i < threads; i++) { //            Callable 带返回值             executorService.submit(new Thread(new Runnable() {                 @Override                 public void run() {                     try {                         System.out.println(Thread.currentThread().getName());                     } catch (Exception e) {                         e.printStackTrace();                     } finally {                         countDownLatch.countDown();                     }                 }             }));         }         countDownLatch.await();         System.out.println("---- end ----");     }      public static void test3() throws Exception{         System.out.println("---- start ----");         ExecutorService executorService = Executors.newWorkStealingPool();         for (int i = 0; i < threads; i++) { //          Runnable 带返回值             FutureTask<?> futureTask = new FutureTask<>(new Callable() {                 /**                  * call                  * @return currentThreadName                  */                 @Override                 public String call() {                     return Thread.currentThread().getName();                 }             });             executorService.submit(new Thread(futureTask));             System.out.println(futureTask.get());         }         System.out.println("---- end ----");     } }
  【温馨提示】
  点赞+收藏文章,关注我并私信回复【面试题解析】,即可100%免费领取楼主的所有面试题资料!

雄安新区条例首次赋予新管委会法律地位雄安新区条例公布这几天来,社会各方面给予了热烈的讨论和解读。其中最强烈的是雄安新区降格了,由过去的中国雄安降为河北雄安。这是一种误解。在此条例出台前,雄安处于筹建阶段,没有明确其法这个Boss有点红,Machenike机械师豪横之夜卖空啦6月15日,Machenike机械师创始人兼总经理王强正式开启直播首秀,直播间豪横撒钱成功出道。而此次直播最大的亮点莫过于重重福利齐炸场,豪横之夜全程高能燃到底,掀起这个夏天最热烈全场景智慧生活开启之匙华为智慧屏V55i华丽问世4月8日,华为春季新品线上发布会正式举行,会上,华为消费者业务CEO余承东发布了两款华为智慧屏新品华为智慧屏X65与华为智慧屏V55i,前者定位高端旗舰,主打2400万超广角AI慧NAS是什么?只是小姐姐的豪宅么?错!大错特错折腾了NAS许久,自己给自己挖了不少的坑,目前貌似基本上都填了,这个过程中自己一些的经验分享给需要的人,或许会对那些还在坑里挣扎的人有些帮助。那么什么是NAS呢或者说NAS能做什么ORICO8口TYPEC笔记本扩展坞解决笔记本连接短板最近连续折腾家里的NAS有一个最大的感触!笔记本木有网口,这样就造成笔记本不能直接通过网线接到NAS的管理口进行操控,虽然可以把无线AP接在管理口然后再通过wifi这样进行操作,可7999元起!探索第三代移动办公的诚意之作华为MateBookX正式发布重量轻至1kg,机身比A4纸还小,3k悬浮全面屏的大视野,把手机装进电脑里,一个屏幕操作两个系统的智慧化办公体验这样的时尚轻薄笔记本,你是否心动?2020年8月19日,华为在上海发超大杯乘风破浪奥利给!7寸大屏荣耀X10Max娱乐办公两不误如果说前段时间荣耀发布会上发布的荣耀X10是超大杯,那么本文的主角荣耀X10Max,就必定是至尊无敌超大杯,它就是了荣耀X10MAX。包装以及全家福一览支持22。5w快充的充电头1华为MatebookX新品你的时尚品质生活臻选注重生活品质,需要随时随地办公的你,是不是十分期待一款颜值高轻薄便携的笔记本?2020年8月19日,华为带来一款全新全面屏轻薄旗舰笔记本华为MateBookX。极致简约设计,机身轻开创多屏时代,2299元起荣耀智慧屏X1系列重塑大屏新格局5月18日,荣耀线上举办了生活与你,一起升级荣耀智慧生活新品发布会。此次发布会,荣耀全面布局智慧场景全产品升级,带来了荣耀智慧屏X1系列智慧平板V6荣耀MagicBookPro荣耀华为MateBookX发布秉承三大经典DNA,引领第三代移动办公移动互联网的快速发展,深刻改变了职场人的办公形态,办公场所从传统的办公室拓展至飞机场高铁站咖啡馆等地,办公时间不再是传统的朝九晚五,及时处理突发工作成为当代职场人的常态。与此同时,大屏超进化华为智慧屏X65携2400万AI慧眼OLED闪耀来袭4月8日,华为新一代旗舰大屏华为智慧屏X65于华为春季新品线上发布会上正式亮相,作为华为智慧屏X系列的首款机型,其凭借顶级的创新交互与音画体验,深度诠释了华为对未来大屏形态的全新探
电池技术新突破,小米11首发的硅氧负极电池真有那么强?目前手机用的锂离子电池的负级多为碳基,如石墨石墨烯等,不过碳材料的能量密度不高,理论比容量只有370mAhg,目前实际量产能达到的最高值大约在300mAhg,已经逼近极限。如果把负年轻人第一辆车?雷军揭露小米首款汽车产品信息自小米集团宣布入局汽车行业以来,其后续的产品计划产品定位产品定价等都颇受业内关注。近日,小米集团董事长雷军针对网络上的诸多问题进行回复。4月6日晚,雷军邀请资深车评人韩路参与个人第华为nova8真的高价低配吗?或许用户体验才是最重要的华为近几年来迅速崛起,手机业务营业额开始超过通讯业务营业额。而华为旗下的手机主要是p系列,mate系列,荣耀,nova这四个系列,自从荣耀被卖出后,华为的中端系列就只剩下nova系工信部智能网联汽车生产企业应依法收集使用和保护个人信息4月7日,工信部发布智能网联汽车生产企业及产品准入管理指南(试行)(征求意见稿),其中提到,智能网联汽车生产企业应遵守网络安全法律法规规定,建立覆盖车辆全生命周期的网络安全防护体系36氪独家美团优选2021年目标2000亿GMV,橙心优选估值已达50亿美金作者董洁杨林编辑杨轩社区团购大战正进入新阶段。36氪从多个独立信源处独家获悉,春节之后各社区团购巨头纷纷确立了2021年的目标美团优选将年GMV锁定在2000亿,并将冲击50006各大APP被曝光!网友怒了你就这么对我们?局外人说局外事各位看官老爷大家好,我是局外人小智今天带大家吃瓜一件和大家息息相关的事!近日,上海复旦大学的孙教授带领团队做了一项打车调研,结果显示,苹果用户更容易被专车优享这类高单小米11评测顶级旗舰的强大竞争对手但却不是最好的选择哈喽,您好!我是原呵呵,点点关注吧,更多精彩内容等着您小米终于发布了出了一部在任何地方上都不落后于其他的安卓旗舰的手机。小米11拥有目前可以最新的最快的高通处理器,即Snapdra警方通报滴滴司机因口角撞死乘客嫌疑人情绪失控,自己报警并投案,已被刑拘长乐公安微博3月15日通报同日,滴滴出行微博发布关于福州快车司机开车冲撞乘客致其身亡的情况通报3月14日凌晨2点左右,福州一名滴滴快车司机高某某接到一名男乘客和一名女乘客后,男乘客工厂用工荒,老板为什么宁愿招临时工,也不给老员工涨工资华为的管理方式是很多企业想要学习,甚至是想要复制下来,很多企业想要但是却得不到,为什么?因为一个企业的价值观以及文化氛围,是任何一家企业都无法复制的。允许你成为一个平凡的人之前任正比特币已经老土了,美国人都在炒这个更摸不着的东西今年2月,数字艺术家毕普(Beeple)的一个名为十字路口的10秒视频短片,在拍卖会上以660万美元的价格售出。同月,一个飞猫留下彩虹痕迹的动画形象,以近60万美元的价格成交。然后荣耀V40轻奢版神似nova8丨骁龙888新机在路上去年荣耀独立后,发布了新机荣耀V40,不过因为是最贵天玑1000机型而反响平平。近日网上曝光了荣耀新机V40轻奢版的早期设计图以及包装盒谍照虽说是V40的轻奢版,但是外观更像是no