1. java線程池原理

        共 12395字,需瀏覽 25分鐘

         ·

        2021-04-10 10:51

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

        優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

        76套java從入門到精通實(shí)戰(zhàn)課程分享

        為什么使用線程池?

        1.降低資源消耗

        通過重復(fù)利用創(chuàng)建好的線程,來降低我們創(chuàng)建和銷毀線程的造成資源的消耗。

        2.提高響應(yīng)速度

        任務(wù)執(zhí)行后,直接通過已經(jīng)創(chuàng)建好的線程執(zhí)行,提高我們的響應(yīng)速度。

        3.提高線程的可管理性

        線程資源和我們服務(wù)器的cpu資源息息相關(guān),不能任意地?zé)o限制創(chuàng)建,不僅消耗我們系統(tǒng)資源,還會(huì)降低系統(tǒng)的響應(yīng)速度。使用線程池可以統(tǒng)一監(jiān)控、調(diào)度和調(diào)優(yōu)。


        線程池分類

        Executor框架的最頂層實(shí)現(xiàn)是ThreadPoolExecutor類,Executors工廠類中提供了以下四種:

        newScheduledThreadPool:定時(shí)任務(wù)線程池

        newSingleThreadScheduledExecutor:只有一個(gè)線程的定時(shí)任務(wù)線程池

        newFixedThreadPool:固定線程數(shù)量的線程池

        newCachedThreadPool:可緩存的線程池

        在實(shí)際項(xiàng)目使用過程中,一般不會(huì)使用自帶的這幾種創(chuàng)建方式,下面會(huì)將解具體原因。


        線程池的核心參數(shù)

        corePoolSize: 核心池的大小。當(dāng)有任務(wù)來之后,就會(huì)創(chuàng)建一個(gè)線程去執(zhí)行任務(wù),當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會(huì)把到達(dá)的任務(wù)放到緩存隊(duì)列當(dāng)中;

        maximumPoolSize: 線程池最大線程數(shù),它表示在線程池中最多能創(chuàng)建多少個(gè)線程;

        keepAliveTime:  表示超出corePoolSize的線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會(huì)終止;

        unit:參數(shù)keepAliveTime的時(shí)間單位,有7種取值,在TimeUnit類中有7種靜態(tài)屬性;

        workQueue: 阻塞隊(duì)列,當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會(huì)把到達(dá)的任務(wù)放到緩存隊(duì)列當(dāng)中,通常初始化時(shí)需要指定隊(duì)列大小;

        threadFactory: 創(chuàng)建線程的工廠,指定線程前綴,來識(shí)別不同業(yè)務(wù)所需的線程池,方便問題的排查;

        handler:拒絕策略,當(dāng)任務(wù)達(dá)到maximumPoolSize最大線程數(shù)量時(shí),通過指定不同的拒絕策略,來對(duì)當(dāng)前任務(wù)做具體的處理。內(nèi)置了有4種策略:

                 AbortPolicy:直接拒絕,拋出異常;

                        CallerRunsPolicy:在主線程中直接執(zhí)行任務(wù)的run方法;

                        DiscardOldestPolicy:阻塞隊(duì)列中丟棄最老的未處理任務(wù),然后執(zhí)行任務(wù);

                        DiscardPolicy:靜默丟棄任務(wù)


        整個(gè)流程

        下圖是線程池主要的4個(gè)流程,結(jié)合了線程池的具體源碼。


        線程池源碼分析

        new線程池時(shí),初始化線程池參數(shù):

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


        調(diào)用線程池的execute():

            public void execute(Runnable command) {
                if (command == null)
                    throw new NullPointerException();
         
                int c = ctl.get();
                //1.小于核心線程池時(shí),創(chuàng)建新的線程
                if (workerCountOf(c) < corePoolSize) {
                    if (addWorker(commandtrue))
                        return;
                    c = ctl.get();
                }
                //2.任務(wù)大于核心線程時(shí),將任務(wù)放到阻塞隊(duì)列中
                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);
                }
                //3.大于最大線程時(shí)
                else if (!addWorker(commandfalse))
                //4.執(zhí)行拒絕策略
                    reject(command);
            }


        Worker分析

        將每個(gè)任務(wù)封住為Worker:

            private final class Worker
                extends AbstractQueuedSynchronizer
                implements Runnable

        然后通過while循環(huán)獲取阻塞隊(duì)列中的任務(wù), 調(diào)用task.run()就會(huì)執(zhí)行我們具體的任務(wù)。

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



        ————————————————

        版權(quán)聲明:本文為CSDN博主「darmi-大張」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

        原文鏈接:

        https://blog.csdn.net/qq_28175019/article/details/115426872





        粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

        ??????

        ??長按上方微信二維碼 2 秒


        感謝點(diǎn)贊支持下哈 

        瀏覽 67
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 91啪国线自产无码14c | 潮吹影音先锋 | 亚洲天堂网一区二区三区 | 小情侣第一次啪啪全程偷拍 | 日批网站在线播放 |