一 应用线程池的益处
- 升高资源耗费:通过重复使用线程缩小线程创立和销毁对资源的造成的耗费。
- 进步响应速度:工作到达时,能够不须要期待线程的创立就能立刻执行。
- 进步线程的可管理性:线程是稀缺资源,无限度的创立会耗费系统资源,还会升高零碎的稳定性,应用线程池能够进行对立的调配,调优和监控。
二 线程池的参数
1. 外围线程数
2. 最大线程数
3. 超过外围线程数的线程放弃工夫
4. 线程放弃工夫的单位
5. 寄存期待线程的队列
6. 线程创立工厂
7. 线程的饱和策略。
三 线程池的工作原理
新的工作来到,先判断线程内工作线程是否达到外围线程数,如果没有,间接创立线程执行工作。
如果外围线程数已满,队列未满,工作则会退出期待队列。
如果期待队列已满,并且没有达到最大线程数,会创立线程,执行工作。
如果期待队列已满,也曾经打到了最大线程数,会触发饱和策略
四 有哪些饱和策略
• ThreadPoolExecutor.AbortPolicy:抛出 RejectedExecutionException 来回绝新工作的解决。
• ThreadPoolExecutor.CallerRunsPolicy:调用执行本人的线程运行工作,也就是间接在调用 execute 办法的线程中运行 (run) 被回绝的工作,如果执行程序已敞开,则会抛弃该工作。因而这种策略会升高对于新工作提交速度,影响程序的整体性能。如果您的应用程序能够接受此提早并且你要求任何一个工作申请都要被执行的话,你能够抉择这个策略。在以后的调用线程执行工作。提交会提早。
• ThreadPoolExecutor.DiscardPolicy:不解决新工作,间接抛弃掉。
• ThreadPoolExecutor.DiscardOldestPolicy:此策略将抛弃最早的未解决的工作申请。
默认的回绝策略是 AbortPolicy 抛出 RejectedExecutionException。
五 一些比照
1.Runnable VS Callable
Runnable 不会返回后果或者抛出异样、Callable 能够。
2.execute() Vs submit();
execute() 提交不须要返回值的工作。
submit() 提交须要返回值得工作。会返回 Future<T> 对象。
能够调用 future.get() 获取后果,get()办法会阻塞以后线程。
get(long timeout,TimeUnit unit)办法能够阻塞一段时间后就返回,但线程可能并未实现,拿不到后果。
3.shutdown() Vs shutdownNow()
shutdown: 敞开线程池,线程池状态变为 shutdown,不承受新工作,但会期待队列里的工作执行结束。
shutdownNow:敞开线程池,线程池状态变为 STOP,会终止正在运行的工作,进行解决排队的工作,并返回期待的 List。
4.isTerminated() Vs isShutDown();
isShutDown 当调用 shutdown()之后就会返回 true;
isTerminated(),当调用 shutdown()之后,等所有工作执行结束才会返回 true;
六 几种常见的线程池及问题
1.FixedThreadPool 固定线程池。外围线程数等于最大线程数,无界队列 Integer.MAX_VALUE 工作多可能 OOM
2.SingleThreadPool 单例线程池。外围线程数和最大线程数为 1 无界队列 工作多可能 OOM
3.cacheThreadPool 缓存线程池。外围线程数为 0 最大线程数为 Integer.MAX_VALUE 同步队列,线程过多
七 外围线程数的大小设置
计算密集型:CPU 个数 +1。
I/ O 密集型:2 倍 CPU 个数。