1.利用Excutors创建不同的线程池满足不同场景的需求
分析:
如果并发的请求的数量非常多,但每个线程执行的时间非常短,这样就会频繁的创建和销毁线程。如此一来,会大大降低系统的效率。 可能出现,服务器在为每个线程创建和销毁线程所消耗的系统资源要比处理实际用户请求的时间更多。那么,有没有一种方法可以重复的利用线程去完成新的任务呢。
2.Fork/Join框架
Java7提供的并行执行任务的框架。
分析:
Fork/join分别将这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务。会出现有的队列里的任务以及完成,其他队列里的任务还没有完成,会导致已经完成任务的线程会被闲置 。解决方法:空闲的线程会从busy的线程处窃取 等待执行的任务;为了减少窃取任务线程以及被窃取任务线程之间的竞争,一般会使用双端队列,被窃取任务的线程永远从双端队列的头部来任务执行,窃取任务线程永远从双端队列的尾部来任务执行。
3.为什么要使用线程池
通过重复利用已经创建的线程,来降低线程创建和销毁的消耗。
使用线程池可以统一的调用分配,调优和监控。
4.Executor框架
是根据一组执行策略调用,调度,执行和控制的异步任务的框架。目的是将任务提交与任务如何运行提交分离开来的机制。
在于其高度的可调节性与灵活性,以尽量满足复杂多变的实际应用场景。
Executors则从简化使用的角度,为码农们提供了各种方便的静态工厂的方法。
在大多数场景下,使用executors提供的5类场景就可以了。
5.启动线程的方式
6.使用ThreadPoolExecutor等构造函数去创建复杂的线程池
分析:
WorkQueue(工作队列):存储用户提交的各个任务。
WoringThreads:工作线程的集合,管理线程的销毁与创建。NewcachedThreadPool,任务压力大,线程池会创建新的工作线程。任务量变小的时候,线程池会闲置一段时间后,结束工作线程。线程池的工作线程被抽象为静态内部类worker.Threadpool维护的就是一组worker对象。
ThreadFactory提供线程池所需的创建线程的逻辑。
如果任务提交被拒绝,比如线程池处于shutdown状态,线程任务需要由处理机制来处理。Java标准库里提供类似ThreadPoolExecutor.aboredpolicy等默认实现。还可按照实际情况扩展自定义相关的处理机制,也就是实现RejecExecutionHandler这个接口。
(1)ThreadPool构造函数:
CorePoolSize:根据不同的线程池设定不同的数量。(可以看Executors里的关于5大线程池的源码)
当任务提交时,如果线程池中的线程数量大于或等于corePoolSize时,把该任务封装成worker对象,放在等待队列中。
(2)线程池的饱和策略:
7.线程池状态: