1、线程池的应用:
为什么要使用线程池,?
1,不使用线程池,每次创建线程都需要在堆上分配内存空间和各种运行资源,线程运行完成后有需要被gc回收,这样频繁的创建和回收线程需要大量的额外开销。
2,如果系统中大量的创建线程对象,jvm可能出现ofm异常。
3,大量的线程去竞争cpu资源时,会产生其他性能的开销,反而会造成整体的性能下降。
线程池的实现原理:
线程池是一个线程集合workerSet(线程池)和一个阻塞队列workQueue组成的。
1,通过execute方法提交任务时,当线程池中的线程数量小于corePoolSize时,新提交的任务将通过创建一个新线程来执行,即使线程池中有空闲的线程。
2,当线程池中线程的数量达到corePoolSize时,新提交的任务将被放入workQueue中,等待线程池执行调度。
3,当workQueue已存满,且maximumPoolSize大于corePoolSize,且线程池中运行的线程数小于maximumPoolSize时,新提交的任务将通过创建新的线程直接进入线程池执行。
4,当线程池中的线程执行完成任务空闲时间,会尝试从workQueue中取头结点任务执行。
5,当线程池中的线程数达到maximumPoolSize且workQueue也存满时,新提交的任务就会触发拒绝策略,由RejectExecutionHandler处理
6,当线程池中的线程数大于corePoolSize,并且未设置allowCoreTreadTimeOut=true 时,空闲时间超过keepAliveTime的线程会被销毁,保持线程池中的线程数为corePoolSize。
7,当设置了allowCoreThreadTimeOut=true时,任何空闲时间超过keepAliveTime的线程会被销毁,最终线程池的线程数为0.
线程池的构造参数:
corePoolSize:核心线程数,当线程池中运行的线程数未达到corePoolSize大小时,每次提交任务都是新建线程运行
其他的略
拒绝策略:
默认策略时AbortPolicy,直接抛出RejectedExecutionException异常,
CallerRunsPolicy:由调用线程直接运行该任务,适用于并发量小的,性能要求不高的,不允许失败的业务
DiscardOldestPolicy:丢弃workQueue中的头部节点线程,并将新任务加入
DiscardPolicy:直接丢弃任务,啥也不干。
java有四种线程池:
newCachedThreadPool:缓存
newFixedThreadPool:固定数量
newSchededThreadPool:定时
newSingleThreadExecutor:单