所在位置 java.util.concurrent.ThreadPoolExecutor
线程池是多线程的处理的形式,多个任务提交到线程池,任务的执行交给线程池去执行。
为什么要创建线程池?
因为多个任务的执行需要多个线程的处理,但是频繁的创建线程和销毁线程会造成资源的消耗和时间的浪费。为了使业务不断的执行,因此创建线程池可以减少线程频繁创建和销毁的资源的开销。
线程池的作用?
1、限制了系统执行中的线程,提高了效率,一次性创建多个,来之即用,减少了频繁创建和销毁的开销
2、线程池方便多个线程的管理,避免频繁创建线程的请求从而使系统崩溃
newCachedThreadPool()
创建一个具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中。
ExecutorService executorService = newCachedThreadPool();
newFixedThreadPool(int nThreads)
创建一个可重用的、具有固定线程数的线程池。
newSingleThreadExecutor()
创建一个只有单线程的线程池,它相当于调用newFixedThread Pool()方法时传入参数为1。
newScheduledThreadPool(int corePoolSize)
创建具有指定线程数的线程池,它可以在指定延迟后执行线程任务。corePoolSize指池中所保存的线程数,即使线程是空闲的也被保存在线程池内。
newSingleThreadScheduledExecutor()
创建只有一个线程的线程池,它可以在指定延迟后执行线程任务。
ExecutorService newWorkStealingPool(int parallelism)
创建持有足够的线程的线程池来支持给定的并行级别,该方法还会使用多个队列来减少竞争。
ExecutorService newWorkStealingPool()
该方法是前一个方法的简化版本。如果当前机器有4个CPU,则目标并行级别被设置为4,也就是相当于为前一个方法传入4作为参数。
在人工手动的给线程池提交任务之后,线程池会先判断核心线程数是否已满,如果没满,就创建新的线程,执行任务,如果核心线程数满了,就判断工作队列是否已满,如果没满,就将任务添加到工作队列中,等待调用。如果工作队列已满,就去判断最大线程数是否已满,没满,就创建的线程,执行该任务,如果已满的情况下,就执行四大拒绝策略中的一个。
线程池状态
RUNNING
能接受新提交的任务,并且也能处理阻塞队列中的任务。
SHUTDOWN
:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时,调用 shutdown()方法会使线程池进入到该状态。
STOP
:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。在线程池处于 RUNNING 或 SHUTDOWN 状态时,调用 shutdownNow() 方法会使线程池进入到该状态。
TIDYING
:如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态。
TERMINATED
:在terminated() 方法执行完后进入该状态,默认terminated()方法中什么也没有做。进入TERMINATED的条件如下:
线程池不是RUNNING状态;
线程池状态不是TIDYING状态或TERMINATED状态;
如果线程池状态是SHUTDOWN并且workerQueue为空;
workerCount为0;
设置TIDYING状态成功。
线程的状态【生命周期】
新建,就绪,运行,阻塞,销毁
这是Java程序中最常见的引用方式,即程序创建一个对象,并把这个对象赋给一个引用变量,程序通过该引用变量来操作实际的对象。当一个对象被一个或一个以上的引用变量所引用时,它处于可达状态,不可能被系统垃圾回收机制回收。
User user = new User();
可能被垃圾回收机制回收,内存足够的情况,不会被GC,程序也可以使用它,当内存不够的时候,就会被系统GC,常用于对于内存比较敏感的程序
系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。GC时候回收
基本没有,虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,虚引用必须和引用队列联合使用。
corePoolSize
(核心工作线程数):当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时。
maximumPoolSize
(最大线程数):线程池所允许的最大线程个数。当队列满了,且已创建的线程数小于maximumPoolSize,则线程池会创建新的线程来执行任务。另外,对于无界队列,可忽略该参数。
keepAliveTime
(多余线程存活时间):当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。
workQueue
(队列):用于传输和保存等待执行任务的阻塞队列。
threadFactory
(线程创建工厂):用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)。
handler
(拒绝策略):当线程池和队列都满了,再加入线程会执行此策略