Executor框架

线程池就是线程的集合,线程池集中管理线程,以实现线程的重用,降低资源消耗,提高响应速度等。线程用于执行异步任务,单个的线程既是工作单元也是执行机制,从JDK1.5开始,为了把工作单元与执行机制分离开,Executor框架诞生了,他是一个用于统一创建与运行的接口。Executor框架实现的就是线程池的功能

java 单线程池执行 单个线程池_线程池

说明:

  • 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();//如果添加到线程池失败,那么主线程会自己去执行该任务

知白守黑,和光同尘