文章目录

Java 中提供​​Executor​​框架用来帮助用户使用线程池

线程池的作用:

  1. 复用线程、控制最大并发数等
  2. 实现任务线程队列缓存策略和拒绝策略
  3. 实现某些与时间相关的功能,如定时执行、周期执行等
  4. 隔离线程环境


一、​​Executor​​ 简介


如图:

【Java】之  Executor_executor

通过Executor框架的根据类Executors,可以创建三种基本的线程池:

  • ​ForkJoinPool​
  • ​ThreadPoolExecutor​
  • ​ScheduledThreadPoolExecutor​

核心方法如下:



(1)​​Executors.WorkStealingPool​

public static ExecutorService newWorkStealingPool(int parallelism) {

return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}

JDK8 引入,创建持有足够线程的线程池支持给定的并行度,并通过使用多个队列减少竞争,此构造方法中把 CPU 数量设置为默认的并行度



(2)​​Executors.newCachedThreadPool​

CachedThreadPool是一个会根据需要创建新线程的线程池

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());

​SynchronousQueue​​是一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。

​corePoolSize​​​是 0,​​maximumPoolSize​​​都最大,无界的。​​keepAliveTime​​为60秒,空闲线程超过 60秒 会被终止。

适用场景:适用于短期异步的小任务,或负载教轻的服务器



(3)​​Executors.newScheduledThreadPool​

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);

//可以直接执行
executor.execute(new JobTaskR("executor", 0));
executor.execute(new JobTaskR("executor", 1));

System.out.println("5S后执行executor3");
//隔5秒后执行一次,但只会执行一次。
executor.schedule(new JobTaskR("executor", 3), 5, TimeUnit.SECONDS);

System.out.println("开始周期调度");

//设置周期执行,初始时6S后执行,之后每2s执行一次
executor.scheduleAtFixedRate(new JobTaskR("executor", 4), 6, 2, TimeUnit.SECONDS);

​scheduleAtFixedRate​​​或者​​scheduleWithFixedDelay​​方法,它们不同的是前者以固定频率执行,后者以相对固定延迟之后执行。

线程数最大至 ​​Integer.MAX_VALUE​​​,存在 ​​OOM​​ 风向。

支持定时及周期性任务执行。

​ScheduleThreadPoolExecutor​​​和​​Timer​​​类似,可以设置延时执行或周期执行,但比​​Timer​​​有更多的功能,​​ScheduledExecutorService​​更安全,功能更强大。

​Timer​​​和​​TimerTask​​只创建一个线程,任务执行时间超过周期会产生一些问题。Timer创建的线程没有处理异常,因此一旦抛出非受检异常,会立刻终止。

与​​newCachedThreadPool​​区别是不回收工作线程



(4)​​Executors.newSingleThreadPool​

核心线程池数量​​corePoolSize​​​和最大数量​​maximumPoolSize​​都设置为1

适用于需要保证顺序执行的场景

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));

适用场景:保证顺序执行



(5)​​Executors.newFixedThreadPool​

可重用固定线程数的线程池

// 获取fixedThreadPool
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(paramInt);

// 内部会调用下面的方法,参数 corePoolSize、maximumPoolSize、keepAliveTime、workQueue
return new ThreadPoolExecutor(paramInt, paramInt, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());

​FixedTheadPool​​​设置的线程池大小和最大数量一样;​​keepAliveTime​​​为0,代表多余的空闲线程会立刻终止;保存任务的队列使用​​LinkedBlockingQueue​​,当线程池中的线程执行完任务后,会循环反复从队列中获取任务来执行。

​FixedThreadPool​​适用于限制当前线程数量的应用场景,适用于负载比较重的服务器。




二、详细


方法图:

【Java】之  Executor_服务器_02