1、为什么要用线程池?
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数 有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。
从JDK1.5 开始,JavaAPI 提供了 Executor 框架让你可以创建不同的线程池。比如单线程池,每次处理一个 任务;数目固定的线程池或者是缓存线程池。
2、 如何创建线程池?
线程池都是通过线程池工厂创建,再调用线程池中的方法获取线程,再通过线程去执行任务方法。 Executors:线程池创建工厂类
1. 自己根据创建线程池的需求来 new 对象(使用) 注意:线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors 返回的线程池对象的弊端如下: 1)FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。 2)CachedThreadPool 和 ScheduledThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
建议自己通过 new 关键字创建 newThreadPoolExecutor
3、创建线程池的方法
newFixedThreadPool():该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新任务提交时,如果线程池中存在空闲的线程,则立即执行;如果没有,则新任务会被暂时存在一个任务队列中,待有线程空闲时再进行处理。
newSingleThreadExecutor(): 该方法返回一个只有一个线程的线程池。若多个任务被提交到该线程池,则多余的任务会被保存在一个任务队列中,待线程空闲,按照先入先出的顺序被执行。
newCachedThreadPool():根据实际情况动态调整线程数量。当新任务提交时,会优先复用空闲的线程;如果所有线程均处于工作状态,则会创建新的线程来进行处理。
newSingleThreadScheduledExecutor():该方法返回一个 ScheduledExecutorService 对象,线程池大小为 1 。SeheduledExectorService 在继承 ExecutorService 的基础上还额外支持定时任务的执行。
newScheduledThreadPool():与 newSingleThreadScheduledExecutor 方法类似,但可以指定线程池中线程的数量。