线程池是如何保持线程存活的

线程池会保持coorPoolSize个线程一致存活,等待submit或者execute提交任务来执行,这个机制是怎么保证的呢?

这其实是归因于ThreadPool中的Workerrun方法,我们来看一看

1.添加Worker

当我们执行execute或者submit提交一个任务之后,如果这时候没有Worker存在会添加一个Worker,精简后的方法如下

private boolean addWorker(Runnable firstTask, boolean core) {
      
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            //...............此处省略一部分代码
            workers.add(w);
            //...............此处省略一部分代码
            workerAdded = true;
            //...............此处省略一部分代码
            if (workerAdded) {
                 t.start();
                workerStarted = true;
            }
        }
        return workerStarted;
    }

可见 addWorker方法如果具备添加一个Worker的条件,就会添加一个Worker实例 ,并调用Worker中的线程tstart方法.

2. Worker的执行

那么我们要看一下Worker中这个线程t是个什么,它的Run方法又执行了什么

private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable{

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

可以看出Worker实现了Runnable接口,
Worker的成员变量thread在构造方法中初始化,传入了this.所以t.start()会执行Worker的run方法
我们看看它的run方法

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

可以看到调用了runWorker,看看精简版的runWorker

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) {
                 task.run();
            }
    }

如果task不为空则调用task.run, 如果为空则通过getTask()获取一个task, 如此往复循环,

那么,如果task为null 并且通过getTask()获取到的也为null, 这个循环就结束了,

那么它如何保证线程池里一直有Worker线程存在等待执行.

关键就在于getTask()方法能不能源源不断的提供不为null的task了

3. 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;
            }
        }
    }

从上面的代码可以看出,只要一些条件不成立,getTask()方法就会不停的从workQueue里面取出来不为空的task返回,如果为空就继续循环.

你可能感兴趣的:(线程池是如何保持线程存活的)