线程池ThreadPoolExecutor源码解析

一、简述

线程池维护着一定的线程数量,通过线程复用减少了线程频繁开启销毁的消耗。
当新任务提交到线程池时:
如果线程池中运行线程数量小于核心线程数量,启动新线程执行提交的任务。
如果线程池中运行线程数量大于或等于核心线程数量,且队列未满,将任务加入队列。此时再次检查,如果没有运行中的线程,启动新线程执行队列中的任务。
如果线程池中运行线程数量大于或等于核心线程数量,但小于最大线程数量,且队列已满,启动新线程执行队列中的任务。
如果线程池中运行线程数量等于最大线程数量,且队列已满,执行拒绝策略。

二、ThreadPoolExecutor属性

1. ctl&wc&rs

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

 // runState is stored in the high-order bits
 private static final int RUNNING    = -1 << COUNT_BITS;
 private static final int SHUTDOWN   =  0 << COUNT_BITS;
 private static final int STOP       =  1 << COUNT_BITS;
 private static final int TIDYING    =  2 << COUNT_BITS;
 private static final int TERMINATED =  3 << COUNT_BITS;

 // Packing and unpacking ctl
 private static int runStateOf(int c)     { return c & ~CAPACITY; }
 private static int workerCountOf(int c)  { return c & CAPACITY; }
 private static int ctlOf(int rs, int wc) { return rs | wc; }

wc:workCount,可以理解为workCount,最多为2^29 - 1。
rs:runState,表示允许状态,对应RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED。
ctl:线程池的状态标志,由wc和rs组合而成。

2. handler

private volatile RejectedExecutionHandler handler;
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

handler为RejectedExecutionHandler接口类型。
该接口只有1个方法:void rejectedExecution(Runnable r, ThreadPoolExecutor executor);用于表示拒绝策略,当线程池中的任务数量超限时,新任务提交后将进入拒绝策略的逻辑。
ThreadPoolExecutor提供了4个RejectedExecutionHandler的实现类,分别是:

(1) AbortPlicy:抛异常RejectedExecutionException
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("Task " + r.toString() +
                                         " rejected from " +
                                         e.toString());
}
(2)DiscardPolicy:不做任何处理
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
(3)DiscardOldestPolicy:放弃队列中的第一个任务,新任务加入队列
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        e.getQueue().poll();
        e.execute(r);
    }
}
(4)CallerRunsPolicy:直接执行新任务
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
   if (!e.isShutdown()) {
        r.run();
    }
}

3. workQueue

workQueue为BlockingQueue类型
当线程池中核心线程数小于任务数时,会将提交的任务保存在workQueue中。
在线程池中主要使用了以下3类BlockingQueue。

(1)有界队列

这一类队列中存放的任务数量有限制,因此称为有界队列。
常用的有界队列是ArrayBlockingQueue和PriorityBlockingQueue,前者适合于FIFO的执行顺序的场景,后者适合于按照优先级的执行顺序的场景。

(2)无界队列

这一列队列中可以存放任意数量的任务,因此称为无界队列。
有用的无界队列为LinkedBlockingDeque

(3)同步队列

主要指SynchronousQueue,不存放任何的任务。

4. threadFactory

threadFactory类型为ThreadFactory接口,是Thread的工厂类,用于根据runnable生成thread。接口中只有一个方法:Thread newThread(Runnable r);

(1)DefaultThreadFactory

线程池中最常使用的ThreadFactory实现类是Executors的静态内部类DefaultThreadFactory。

static class DefaultThreadFactory implements ThreadFactory {
   private static final AtomicInteger poolNumber = new AtomicInteger(1);
   private final ThreadGroup group;
   private final AtomicInteger threadNumber = new AtomicInteger(1);
   private final String namePrefix;

   DefaultThreadFactory() {
       SecurityManager s = System.getSecurityManager();
       group = (s != null) ? s.getThreadGroup() :
                             Thread.currentThread().getThreadGroup();
       namePrefix = "pool-" +
                     poolNumber.getAndIncrement() +
                    "-thread-";
   }

   public Thread newThread(Runnable r) {
       Thread t = new Thread(group, r,
                             namePrefix + threadNumber.getAndIncrement(),
                             0);
       if (t.isDaemon())
           t.setDaemon(false);
       if (t.getPriority() != Thread.NORM_PRIORITY)
           t.setPriority(Thread.NORM_PRIORITY);
       return t;
   }
}
(2)Worker

threadFactory在线程池中的用处就是在Worker的构造器中。
Worker是对提交到线程池的任务的封装。

Worker(Runnable firstTask) {
   setState(-1); // inhibit interrupts until runWorker
    this.firstTask = firstTask;
    this.thread = getThreadFactory().newThread(this);
}

state设置为-1是为了防止中断方法

void interruptIfStarted() {
    Thread t;
    if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
        try {
            t.interrupt();
        } catch (SecurityException ignore) {
        }
    }
}
</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值