线程池原理

为什么需要线程池

java线程的创建非常昂贵,需要jvm和os配合完成大量工作,必须为线程堆栈分配和初始化大量内存块,其中包含至少1mb的栈内存,需进行系统调用,以便在os中创建和注册本地线程。频繁创建和销毁线程是非常低效,必须使用线程池,线程池主要解决了两个问题
1)提升性能:线程池能独立负责线程的创建、维护和分配;
2)线程管理:每个java线程池会保持一些基本的线程统计信息;

线程池的类与接口

类/接口简介
Executorjava异步目标的执行者接口,执行任务目标
ExecutorService继承Executor 执行者服务接口,对外提供接受异步任务
AbstractExecutorService抽象类,实现ExecutorService接口,提供默认实现
ThreadPoolExecutor即为线程池类,继承AbstractExecutorService抽象类
ScheduledExecutorServcie接口,继承ExecutorService,可以完成延迟和周期性任务的调度。
ScheduledThreadPoolExecutor继承ThreadPoolExecutor 实现ScheduledExecutorService,类似Timer,高并发程序中性能优于Timer

线程池类关系图

线程池的创建与使用

Exeutors 静态工厂里类创建线程池

静态方法简介
newSingleThreadExecutor()创建只有一个线程的线程池,可以保证所有任务按顺序执行
newFixedThreadPool(int n)创建固定大小的线程池
newCachrThreadPool()创建不限制线程数量的线程池,任何提交的任务都立即执行
newScheduledThreadPool()创建可定期或者延时执行任务的线程池

由于使用Executors创建的线程池使用无界队列可能导致的内存资源耗尽,或者不限制创建线程个数而导致的CPU资源耗尽等问题, 应该杜绝使用这些便捷方法,而是直接使用线程池ThreadPoolExecutor的构造器。

线程池的标准创建方式

通过构造器ThreadPoolExecutor和ScheduledThreadPoolExecutor的构造方法完成,线程池构造器主要参数如下;

项目Value
int corePoolSize 核心线程数即使线程空闲也不会回收
int maximumPoolSize线程数的上限
long keepAliveTime TimeUint unit线程最大空闲时长
BlockingQueue workQueue任务排队的队列
ThreadFactory threadFactory新线程的产生方式
RejectedExecutorionHandler handler拒绝策略
线程池队列

如果线程池的核心线程都在忙,那么所接收到的目标任务缓存在阻塞队列中,BlockingQueue 线程池阻塞队列是超级接口,实现类有

项目Value
ArrayBlockQueue基于数组实现的有界阻塞队列,先进先出排序。
LinkedBlockingQueue基于链表实现的有界阻塞队列,先进先出排序任务
PriorityBlockingQueue具有优先级的无界阻塞队列
DelayQueue无界延迟队列 底层基于PriporityBlockingQueue实现,队列每个元素都有过期时间,已过去的元素才会出队。
SynchronousQueue同步队列,不存储元素的阻塞队列,每个插入操作,必须等到另一个线程的调用移除操作,否则插入操作一直处于阻塞状态,newCachrThreadPool 创建的线程池使用此队列
调度器的钩子方法

ThreadPoolExecutor线程池调度器为每个任务执行前后提供了够足方法ThreadPoolExecutor类提供了三个钩子方法

  1. protected void beforeExecute(Thread t, Runable r) { }
    执行任务前的钩子方法
  2. protected void afterExecute(Runable r,Throwable t){ }
    执行任务后的钩子方法
  3. protected void terminated (){ }
    线程池终止时的钩子方法
线程池的拒绝策略

任务被拒绝有两种情况,线程池已关闭或者工作队列已满且maximumPoolSize已满,拒绝策略都会调用 RejectedExecutionHandler 实例的rejectedExecution方法,RejectedExecutionHandler 拒绝策略接口 juc提供了四种实现;

策略种类简介
AbortPolocy 拒绝策略直接抛出异常,默认策略
DiscardPolicy抛弃策略 直接抛弃任务,不抛异常
DiscardOldestPolicy抛弃最老任务策略
CallerRunsPolicy调用者执行策略,在新任务被添加到线程池时,如果添加失败,那么提交任务线程会自己去执行该任务,不会使用线程池中的线程去执行新任务。
线程池状态
状态简介
runing线程池创建后的初始状态,可以执行任务
shutdown不接受新任务 ,工作队列中的任务执行完毕
stop不接受新任务,不处理队列中的任务,并中断所有工作线程
tidying所有任务已终止或处理完成,将会执行 terminated()钩子方法
terminated执行terminated()钩子方法后的状态
线程池关闭的三个方法
  1. shutdown 方法关闭线程池,拒绝接受新任务,添加新任务会抛出异常,线程池不会立刻退出,知道添加到线程池的任务执行完成才退出。
  2. shutdownnow方法,线程池会立即变成stop,并试图停止正在执行的线程,不再处理阻塞队列中等待的任务。
  3. awaitTermination 等待线程池完成关闭,才返回。在调用线程池的shutdown()与shutdownNow()方法时,当前线程会立即返回,不会一直等待直到线程池完成关闭。如果需要等到线程池关闭完成,可以调用awaitTermination()方法。

线程池调度流程

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值