java-并发-源码-ThreadPoolExecutor

一. 状态成员

ctl线程数量和线程状态
29位以上管理进程状态,29位以下管理线程数量
五种状态的数字,表示他们的运行的先后顺序。

	private static final int COUNT_BITS = Integer.SIZE - 3;		//29
	private static final int RUNNING    = -1 << COUNT_BITS;		//e0000000
    private static final int SHUTDOWN   =  0 << COUNT_BITS;		//0
    private static final int STOP       =  1 << COUNT_BITS;		//20000000
    private static final int TIDYING    =  2 << COUNT_BITS;		//40000000
    private static final int TERMINATED =  3 << COUNT_BITS;		//60000000

RUNNING:接收新任务,处理队列
SHUTDOWN:不接收新任务,但是处理队列
STOP:不接收新任务,不处理队列,中断正在处理的任务
TIDYING:所有的任务终结,workerCount为0,变成TIDYING的线程会调用terminated()钩子方法
TERMINATED:terminated()调用完成了
ctl包含两个内容workerCount和runState,打包和拆包ctl代码如下:

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 
	private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }	//e0000000
    private static int workerCountOf(int c)  { return c & CAPACITY; }   //1fffffff
    private static int ctlOf(int rs, int wc) { return rs | wc; }

状态改变
检查线程池当前状态,由于不同的状态顺序是固定的,不可逆,可以利用位运算判断状态的先后

	//c比s小
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }
	//c比s大
    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

状态的维护在ThreadPoolExecutor类中,公共数据由ReentrantLock锁保护

shutdown方法

    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

advanceRunState方法通过compareAndSet更新线程池的状态

 private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();		//获取ctl包
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

二. 任务执行

线程池状态

private final BlockingQueue<Runnable> workQueue;            	 //任务缓存队列,用来存放等待执行的任务
private final ReentrantLock mainLock = new ReentrantLock();   	 //线程池的主要状态锁
private final HashSet<Worker> workers = new HashSet<Worker>(); 	 //用来存放工作集
private volatile long  keepAliveTime;   						 //线程存货时间   
private volatile boolean allowCoreThreadTimeOut;  				 //是否允许为核心线程设置存活时间
private volatile int   corePoolSize;     						 //线程池大小
private volatile int   maximumPoolSize; 						 //线程池最大能容忍的线程数
private volatile int   poolSize;       							 //线程池中当前的线程数
private volatile RejectedExecutionHandler handler; 				 //任务拒绝策略
private volatile ThreadFactory threadFactory; 				     //线程工厂,用来创建线程
private int largestPoolSize;								     //用来记录线程池中曾经出现过的最大线程数
private long completedTaskCount; 							     //用来记录已经执行完毕的任务个数

execute()
首先添加woker,如果添加失败了,任务没有启动

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

addWorker逻辑中有一段,检查状态是否可以接受新的task

    if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null &&! workQueue.isEmpty()))
        return false;

疑问:状态为SHUTDOWN,添加的task为null,workQueue非空,难道可以接受整个空任务吗??

addworker代码
private boolean addWorker(Runnable firstTask, boolean core)分成两份部分
首先增加woker数量,调用compareAndIncrementWorkerCount是存在失败的可能,这是个cas操作,如果内存中的值c和要设置的值c不一致,会重试

    retry:
    for (;;) {
        ...
        for (;;) {
			...
            if (compareAndIncrementWorkerCount(c))	//
                break retry;
            c = ctl.get();  // Re-read ctl
            if (runStateOf(c) != rs)
                continue retry;
        }
    }

利用传入的Runnable,创建一个Worker对象
任务被封装成了worker,线程池中的worker被放到workers这hashset中

boolean workerStarted = false;
    boolean workerAdded = false;
    Worker w = null;
    try {
        w = new Worker(firstTask);	
        final Thread t = w.thread;
        if (t != null) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                int rs = runStateOf(ctl.get());

                if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive())									 // precheck that t is startable
                        throw new IllegalThreadStateException();
                    workers.add(w);
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                t.start();
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;

如果添加失败了,调用addWorkerFailed回滚,去掉workers,减少worker数量

    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                workers.remove(w);
            decrementWorkerCount();
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }

回滚之后需要调用tryTerminate,判断是否需要terminate
疑问:为什么runStateAtLeast(c, TIDYING)这条件满足了,就不tryTerminate了?

    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

三. worker

构造方法

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

状态设置为RUNNING,firstTask设置为传入的Runnable,thread由内部持由ThreadPoolExecutor的ThreadFactory创建
Worker实现的Runnable接口,实现的run方法执行runWorker(this)
runWorker
进入runWorker之后,执行while循环,持续调用getTask方法,更新task,直到无法取出数据之后才会结束;

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
				//如果pool停止了,保证Thread是interrupted状态
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

getTask代码

   private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

四. 用法

如果线程池内的线程并行执行,如果线程更多会进入队列中等待;

public class MainClass {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5));

        for(int i=0;i<15;i++){
            MyTask myTask = new MyTask(i);
            executor.execute(myTask);
            System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
                    executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
        }
        executor.shutdown();
    }
}
class MyTask implements Runnable {
    private int taskNum;

    public MyTask(int num) {
        this.taskNum = num;
    }

    @Override
    public void run() {
        System.out.println("正在执行task "+taskNum);
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task "+taskNum+"执行完毕");
    }
}

posted @ 2016-09-06 22:21  zhangshihai1232  阅读(238)  评论(0)    收藏  举报