Java并发编程之线程池方法

78 阅读2分钟

ThreadPoolExecutor

ThreadPoolExecutorJava提供的线程池的实现类

构造方法
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {

通过 Java并发编程之如何设计线程池了解了线程池的基本设计原理,对构造方法中的参数已经有了初步了解。

  • corePoolSize:核心线程数
  • maximumPoolSize:线程池最大线程数量
  • keepAliveTime:非核心线程空闲存活时间
  • unit:非核心线程空闲存活时间单位
  • workQueue:阻塞队列
  • threadFactory:线程工厂,通过工厂方法创建线程,可以自定义名称
  • handler:拒绝策略处理器

实例方法

  • public void execute(Runnable command)

执行任务command

  • public <T> Future<T> submit(Callable<T> task)

提交任务task,通过返回值Future可以获取执行结果

  • public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)

提交任务集合tasks中的所有任务,并且通过List<Future<T>>获取所有执行结果

  • public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)

提交任务集合tasks中的所有任务,但是有超时时间,超过时间就不再执行,通过List<Future<T>>获取所有执行结果

  • public <T> T invokeAny(Collection<? extends Callable<T>> tasks)

提交tasks中的所有任务,哪个任务先执行完就返回这个任务结果,其他任务取消

  • public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)

提交tasks中的所有任务,哪个任务先执行完就返回这个任务结果,其他任务取消,任务执行有超时时间

Executors

Executors是线程池的工厂类,通过以下方法创建了几种默认的线程池:

  • newFixedThreadPool(int nThreads)

创建固定大小的线程池,核心线程数和最大线程数相等corePoolSize=maximumPoolSize

  • newSingleThreadExecutor()

创建单个线程的线程池,corePoolSize=1,maximumPoolSize=1可以保证多个任务顺序执行

  • newCachedThreadPool()

创建带缓存功能的线程池,corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,根据业务需要创建新线程,业务越多线程数就越多,旧线程可用时进行复用,空闲60S后释放线程,没有核心线程所有线程都可以被回收,适合任务量大但是耗时比较短的情况

  • newScheduledThreadPool(int corePoolSize)

创建可以定时执行的线程池maximumPoolSize=Integer.MAX_VALUE

面试题

为什么阿里巴巴代码规范中禁止使用Executors来创建线程池?

  • FixedThreadPoolSingleThreadExecutor允许队列的长度是Integer.MAX_VALUE,大量任务堆积时可能会产生OOM
  • CachedThreadPoolScheduledThreadPool允许线程创建数量是Integer.MAX_VALUE,创建大量线程可能会产生OOM

使用线程池的好处是:可以使用多个线程;可以处理多个任务