线程池的七个参数和五种线程池
Executor框架
线程池就是线程的集合,线程池集中管理线程,以实现线程的重用,降低资源消耗,提高响应速度等。线程用于执行异步任务,单个的线程既是工作单元也是执行机制,从JDK1.5开始,为了把工作单元与执行机制分离开,Executor框架诞生了,他是一个用于统一创建与运行的接口。Executor框架实现的就是线程池的功能
说明:
- Executor 执行器接口,该接口定义执行Runnable任务的方式。
- ExecutorService 该接口定义提供对Executor的服务。
- ScheduledExecutorService 定时调度接口。
- AbstractExecutorService 执行框架抽象类。
- ThreadPoolExecutor JDK中线程池的具体实现。
- Executors 线程池工厂类。
ThreadPoolExecutor(线程池类)
线程池是一个复杂的任务调度工具,它涉及到任务、线程池等的生命周期问题。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
线程池的七个参数
-
corePoolSize:核心线程数。
-
maximumPoolSize:最大线程数。
-
keepAliveTime:线程存活时间。当线程数大于core数,那么超过该时间的线程将会被终结。
-
unit:keepAliveTime的单位。java.util.concurrent.TimeUnit类存在静态静态属性: NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS
-
workQueue:Runnable的阻塞队列。若线程池已经被占满,则该队列用于存放无法再放入线程池中的Runnable。
-
threadFactory:创建一个新线程时使用的工厂,可以用来设定线程名、是否为守护线程等等
-
handler:拒绝策略
五种线程池
ExecutorService threadPool = null;
//有缓冲的线程池,线程数 JVM 控制,线程太多会导致CUP一直进行切换,阻塞队列使用的是SynchronousQueue(容量为0),不希望任务堆积
threadPool = Executors.newCachedThreadPool();
//固定大小的线程池,核心线程数和最大线程数保持一致,希望以恒定的处理速度使用线程
threadPool = Executors.newFixedThreadPool(3);
//可创建最大线程为int最大值,线程太多会导致CPU频繁切换
threadPool = Executors.newScheduledThreadPool(2);
//单线程的线程池,只有一个线程在工作,队列长度为int最大值,可能会堆积大量请求
threadPool = Executors.newSingleThreadExecutor();
//默认线程池,可控制参数比较多
threadPool = new ThreadPoolExecutor();
// 基于工作窃取算法,其中任务可以生成其他较小的任务,这些任务将添加到并行处理线程的队列中。如果一个线程完成了工作并且无事可做,则可以从另一线程的队列中“窃取”工作
threadPool = Executors.newWorkStealingPool();
阻塞队列
BlockingQueue<Runnable> workQueue = null;
workQueue = new ArrayBlockingQueue<>(5);//基于数组的先进先出队列,有界
workQueue = new LinkedBlockingQueue<>();//基于链表的先进先出队列,无界
workQueue = new SynchronousQueue<>();//无缓冲的等待队列,无界
线程池的拒绝策略
阿里出品的规范不建议使用这些拒绝策略,建议自定义策略(可保存到redis,kafaka或日志文件等中)
RejectedExecutionHandler rejected = null;
rejected = new ThreadPoolExecutor.AbortPolicy();//默认,队列满了丢任务抛出异常
rejected = new ThreadPoolExecutor.DiscardPolicy();//队列满了丢任务不异常
rejected = new ThreadPoolExecutor.DiscardOldestPolicy();//将最早进入队列的任务删,之后再尝试加入队列
rejected = new ThreadPoolExecutor.CallerRunsPolicy();//如果添加到线程池失败,那么主线程会自己去执行该任务
知白守黑,和光同尘