溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

線程池源碼解讀的示例分析

發(fā)布時間:2021-09-10 11:00:19 來源:億速云 閱讀:114 作者:柒染 欄目:大數(shù)據(jù)

線程池源碼解讀的示例分析,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

一、execute

ctl作為AtomicInteger類存放了類中的兩種信息,在其中由高3位來保存線程池的狀態(tài),后29位來保存此時線程池中的Woker類線程數(shù)量(由此可知,線程池中的線程數(shù)量最高可以接受大約在五億左右)。由此可見給出的runStateOf()和workerCountOf()方法分別給出了查看線程狀態(tài)和線程數(shù)量的方法。

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();

        //如果運行的線程數(shù)小于corePoolSize,嘗試創(chuàng)建一個新線程(Worker),并執(zhí)行它的第一個command
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //線程數(shù)大于corePoolSize,將線程放入任務(wù)隊列
        //第一次校驗線程池在運行狀態(tài)
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            //第二次校驗,防止在第一次校驗通過后線程池關(guān)閉。如果線程池關(guān)閉,在隊列中刪除task并拒絕task
            if (! isRunning(recheck) && remove(command))
                reject(command);
            //如果線程數(shù)=0(線程都死掉了,比如:corePoolSize=0),新建線程且未指定firstTask,僅輪詢?nèi)蝿?wù)隊列
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //任務(wù)隊列已滿,嘗試創(chuàng)建新線程執(zhí)行task,創(chuàng)建失敗后拒絕task
        //創(chuàng)建失敗原因:1.線程池關(guān)閉;2.線程數(shù)已經(jīng)達到maxPoolSize
        else if (!addWorker(command, false))
            reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        //外層循環(huán)判斷線程池的狀態(tài)
        for (;;) {
            int c = ctl.get();
            //線程池狀態(tài)
            int rs = runStateOf(c);
            //線程池狀態(tài):RUNNING = -1、SHUTDOWN = 0、STOP = 1、TIDYING = 2、TERMINATED
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;
            //用CAS的方式對線程數(shù)量進行+1操作
            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 {

            //worker實現(xiàn)了Runable接口
            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是一個worker數(shù)組
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    //啟動線程,執(zhí)行的就是worker中的run()
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

Worker類:

private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable//Worker是一個線程
    {
        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;
            //把當(dāng)前Worker包裝成一個thread
            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 {
            //如果這個worker還沒有執(zhí)行過在構(gòu)造方法就傳入的任務(wù),那么在這個方法中,會直接執(zhí)行這一任務(wù),如果沒有,則會 
            //嘗試去從任務(wù)隊列當(dāng)中去取的新的任務(wù)。
            //在執(zhí)行完畢后,工作線程的使命并沒有真正宣告段落。在while部分worker仍舊會通過getTask()方法試圖取得新 
            //的任務(wù)。下面是getTask()的實現(xiàn)。
            while (task != null || (task = getTask()) != null) {
                w.lock();
                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);
        }
    }
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;
            }
        }
    }

二、submit

    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    /**
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

可見,submit將普通的runnable包裝成FutureTask并返回,再調(diào)用execute去執(zhí)行。

關(guān)于線程池源碼解讀的示例分析問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI