并发包中的线程池

226 阅读2分钟

1 类ThreadPoolExecutor

主要参数:

  • corePoolSize 核心线程数,空闲的时候保持的线程数量
  • maximumPoolSize 当核心线程数用完了,任务队列也用完了以后能增加的最大线程的数量
  • keepAliveTime 非核心线程存活的时间
  • workQueue 阻塞队列 [问题?为什么用阻塞队列,因为线程安全吗?]
  • threadFactory
  • handler 拒绝策略(4种,丢弃,丢弃最长的,抛出异常,用提交线程执行)
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler

2 Executors.newFixedThreadPool

核心线程数和最大线程数相等,存活的时间为0,使用阻塞的队列为LinkedBlockingQueue 注意这里的泛型类型为Runnable,也就是无论提交了啥Runnable还是Callable都是按照线程基本的运行方式来进行运行,即运行Runnable.run()

new ThreadPoolExecutor(nThreads,
                      nThreads,
                      0L, TimeUnit.MILLISECONDS,
                      new LinkedBlockingQueue<Runnable>());

3 Executors.newSingleThreadExecutor()

单线程的线程池,任务队列无限大,任何时刻都只有一个线程在线程池里面,当里面的线程出现问题的时候,能够创建新的线程来执行任务

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

4 Executors.newCachedThreadPool()

注意这里使用的任务队列SynchronousQueue()表示每一个时刻只有当有其他线程来取的时候,才能插入;所以每个时候插入任务到该队列中都会失败,而核心线程数量为0,所以去创建新的线程执行线程。

适用场景:线程池停顿时间长,任务执行时间短。因为线程池里面的线程很快会被回收,所以不消耗任何资源。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

5 Executors.newScheduledThreadPool

创建一个可以延迟执行任务或者定时任务

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}