线程池

223 阅读2分钟
线程池
线程池参数
public ThreadPoolExecutor(int corePoolSize, // 核心线程数
                          int maximumPoolSize, // 最大线程数
                          long keepAliveTime, // 空闲线程的保留时间
                          TimeUnit unit, // 空闲线程保留的时间的单位
                          BlockingQueue<Runnable> workQueue, // 用于保存等待执行任务的阻塞队列
                          ThreadFactory threadFactory, // 用于设置创建线程的工厂
                          RejectedExecutionHandler handler // 拒绝策略) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
        null :
    AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

  • RejectedExecutionHandler(饱和策略)

    • AbortPolicy:直接抛出异常(默认)
    • CallerRunsPolicy:只用调用者所在线程来运行任务。
    • DiscardPolicy:不处理,丢弃掉
    • DiscardOldestPolicy:丢弃队列里最靠前的一个任务,并执行当前任务
  • BlockingQueue(阻塞队列)

    • ArrayBlockingQueue(有界队列)
    • LinkedBlockingQueue(无界队列)
    • SynchronousQueue(同步队列)
    • PriorityBlockingQueue(带有优先级的无界阻塞队列)
    • DelayQueue(支持延时获取元素的无界阻塞队列)
  • ThreadFactory(用来创建线程池中的线程,通常用默认的即可)

  • TimeUnit

    • TimeUnit.SECONDS(秒)
    • TimeUnit.MILLISECONDS(毫秒)
  • 关于核心线程数,最大线程数等要怎么理解

当一个任务要被添加进线程池时,有以下四种执行策略:

  1. 线程数量未达到 corePoolSize且小于maximumPoolSize,则新建一个线程(核心线程)执行任务。
  2. 线程数量达到了 corePoolsSize,则将任务移入队列等待。
  3. 队列已满,新建非核心线程执行任务。
  4. 队列已满,总线程数又达到了 maximumPoolSize,就会由 RejectedExecutionHandler 抛出异常。

如何创建一个线程
  • 通过Executors

    • newSingleThreadPool
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1, // 核心线程数和最大线程数都是1
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }								// 阻塞对列用的是LinkedBlockingQueue
    
    • newCachedThreadPool
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,// 核心线程数0,最大线程数MAX
                                      60L, TimeUnit.SECONDS,// 存活时间60ms
                                      new SynchronousQueue<Runnable>());
    }								  // 阻塞队列用的是SynchronousQueue
    
    • newFixedThreadPool
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,// 核心线程数和最大线程数相等
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }								  // 阻塞队列用的是LinkedBlockingQueue
    
    • newScheduledThreadPool
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }		  // 阻塞队列用的是DelayedWorkQueue
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    
合理配置
  • CPU密集型任务,需要尽量压榨CPU,参考值可以设为NCPU + 1
  • IO密集型任务,参考值可以设为2 * NCPU