java Executors源码简析

来源:互联网 发布:淘宝店铺怎么登录 编辑:程序博客网 时间:2024/06/15 02:32
package a160229;import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ExecutorsTest {public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(5);for(int i=1; i<=10; i++) {threadPool.execute(new Task(i));}threadPool.shutdown();while(!threadPool.isTerminated());System.out.println("all over!");}}class Task implements Runnable {int id;Task(int id) {this.id = id;}@Overridepublic void run() {try {Thread.sleep(new Random().nextInt(10)*1000);} catch (InterruptedException e1) {// TODO Auto-generated catch block//e1.printStackTrace();System.out.println("task" + id + "is interrupted");}System.out.println("task" + id + " is running ");try {Thread.sleep(new Random().nextInt(10)*1000);} catch (InterruptedException e) {// TODO Auto-generated catch block//e.printStackTrace();System.out.println("task" + id + "is interrupted");

让我们来以这段代码为例简单分析Executor源码。

public static ExecutorService  newFixedThreadPool(int nThreads) {         return new ThreadPoolExecutor(nThreads, nThreads,                                       0L, TimeUnit.MILLISECONDS,                                       new LinkedBlockingQueue<Runnable>());     }

newFixedThreadPool 是创建一个固定大小的线程池,固定线程数为nThreads,如果当前线程数不足以满足当前任务数,未被线程受理的任务会进入一个队列(这里是LinkedBlokingQueue,下一篇文章分析这个队列)。

public  ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime,                              TimeUnit unit,                              BlockingQueue<Runnable> workQueue) {        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,             Executors.defaultThreadFactory(), defaultHandler);    }

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.corePoolSize = corePoolSize;        this.maximumPoolSize = maximumPoolSize;        this.workQueue = workQueue;        this.keepAliveTime = unit.toNanos(keepAliveTime);        this.threadFactory = threadFactory;        this.handler = handler;    }

构造函数中需要说明的形参,corePoolSize是在未设置allowCoreThreadTimeOut的情况下,池中所维持的线程数,即便其中线程是空闲状态;maximumPoolSize是池所允许的最大线程数。

如此,一个线程池就建好了,当然此时还没有线程。

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);    }

让我们来看ctl是什么玩意

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 More ...runStateOf(int c)     { return c & ~CAPACITY; }     private static int More ...workerCountOf(int c)  { return c & CAPACITY; }     private static int More ...ctlOf(int rs, int wc) { return rs | wc; }

Ctl就是control,是一个32bit二进制数(一个int),高3位代表了线程池的状态(RUNNING等),低29位表示最大线程数(非用户设置数,当用户设置数大于此数时,用户设置数并不会被重置,而是以此数为标准)。

private boolean addWorker(Runnable firstTask, boolean core) {        retry:         for (;;) {             int c = ctl.get();             int rs = runStateOf(c);              // Check if queue empty only if necessary.             if (rs >= SHUTDOWN &&                ! (rs == SHUTDOWN &&                    firstTask == null &&                    ! workQueue.isEmpty()))                 return false;              for (;;) {                 int wc = workerCountOf(c);                 if (wc >= CAPACITY ||                     wc >= (core ? corePoolSize : maximumPoolSize))                     return false;                 if (compareAndIncrementWorkerCount(c))                     break retry;                 c = ctl.get();  // Re-read ctl                 if (runStateOf(c) != rs)                    continue retry;                 // else CAS failed due to workerCount change; retry inner loop             }         }          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 {                     // Recheck while holding lock.                     // Back out on ThreadFactory failure or if                     // shut down before lock acquired.                     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;     }

addWorker就是要向池中添加线程了,其中会有池状态检查(主要包括线程池是否处于要关闭状态、池中线程数是否到达阈值等)。

workers.add(w)就是向池(workers是一个hashset)中放入工作线程,而后t.start()便启动了工作线程,这里t(thread)和w(worker)之间的数据结构需要关注一下。

private final class Worker         extends AbstractQueuedSynchronizer         implements Runnable     {         private static final long serialVersionUID = 6138294804551838833L;         final Thread thread;         Runnable firstTask;         volatile long completedTasks;         Worker(Runnable firstTask) {             setState(-1); // inhibit interrupts until runWorker             this.firstTask = firstTask;             this.thread = getThreadFactory().newThread(this);         }。。。。public void run() {             runWorker(this);         }。。。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();                // If pool is stopping, ensure thread is interrupted;                // if not, ensure thread is not interrupted.  This                // requires a recheck in second case to deal with                // shutdownNow race while clearing interrupt                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);        }    }}

可以看出runWorker才是工作线程真正的执行代码,其中task.run就是我们定义的任务的执行,执行过程中同样会检查线程池状态,如下。

if ((runStateAtLeast(ctl.get(), STOP) ||                     (Thread.interrupted() &&                      runStateAtLeast(ctl.get(), STOP))) &&                    !wt.isInterrupted())                    wt.interrupt();

当线程池处于STOP状态时,线程会被标记打断,但当前线程会继续执行,也即当前任务会继续执行完。while (task != null || (task = getTask()) != null)中,getTask时如果状态为STOP,即使队列中有任务,其也会返回null,这就会使得runWorker 方法中的for循环被终止,从而执行后面的processWorkerExit

private void  processWorkerExit(Worker w, boolean completedAbruptly) {         if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted             decrementWorkerCount();          final ReentrantLock mainLock = this.mainLock;         mainLock.lock();        try {            completedTaskCount += w.completedTasks;            workers.remove(w);        } finally {            mainLock.unlock();        }        tryTerminate();        int c = ctl.get();        if (runStateLessThan(c, STOP)) {            if (!completedAbruptly) {                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;                if (min == 0 && ! workQueue.isEmpty())                    min = 1;                if (workerCountOf(c) >= min)                    return; // replacement not needed            }            addWorker(null, false);        }    }

这里的关键方法就是workers.remove,此后相应worker已被移除workers(hashset)。

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))) {//设置TIDYING                     try {                         terminated();                     } finally {                         ctl.set(ctlOf(TERMINATED, 0));//执行完terminated后,池变为TERMINATED状态                         termination.signalAll();//Wakes up all waiting threads.                     }                     return;                 }             } finally {                 mainLock.unlock();             }             // else retry on failed CAS         }     }

tryTerminate();会试图STOP-> TERMINATED

最后看一下shutdown方法

public void shutdown() {        final ReentrantLock mainLock = this.mainLock;        mainLock.lock();        try {            checkShutdownAccess();            advanceRunState(SHUTDOWN);//池状态变为SHUTDOWN            interruptIdleWorkers();//将所有worker标记打断            onShutdown(); // hook for ScheduledThreadPoolExecutor        } finally {            mainLock.unlock();        }        tryTerminate();    }

while(!threadPool.isTerminated()),isTerminated就是检查线程池状态(ctl的值)是否为TERMINATED









0 0
原创粉丝点击