成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

線程池源碼分析

enda / 2074人閱讀

摘要:線程池的作用線程池能有效的處理多個(gè)線程的并發(fā)問題,避免大量的線程因?yàn)榛ハ鄰?qiáng)占系統(tǒng)資源導(dǎo)致阻塞現(xiàn)象,能夠有效的降低頻繁創(chuàng)建和銷毀線程對性能所帶來的開銷。固定的線程數(shù)由系統(tǒng)資源設(shè)置。線程池的排隊(duì)策略與有關(guān)。線程池的狀態(tài)值分別是。

線程池的作用

線程池能有效的處理多個(gè)線程的并發(fā)問題,避免大量的線程因?yàn)榛ハ鄰?qiáng)占系統(tǒng)資源導(dǎo)致阻塞現(xiàn)象,能夠有效的降低頻繁創(chuàng)建和銷毀線程對性能所帶來的開銷。

線程池的真相

真正線程池的實(shí)現(xiàn)是通過ThreadPoolExecutor,ThreadPoolExecutor通過配置不同的參數(shù)配置來創(chuàng)建線程池。下面簡單的介紹一下各個(gè)線程池的區(qū)別和用處。

fixThreadPool 固定線程池
Executor executor = Executors.newFixedThreadPool(10);
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
    }

我的理解這是一個(gè)有指定的線程數(shù)的線程池,有核心的線程,里面有固定的線程數(shù)量,響應(yīng)的速度快。固定的線程數(shù)由系統(tǒng)資源設(shè)置。

注:核心線程是沒有超時(shí)機(jī)制的,隊(duì)列大小沒有限制,除非線程池關(guān)閉了核心線程才會被回收。

CacheThreadPool 緩存線程池
    Executor executor =  Executors.newCachedThreadPool();
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue());
    }

構(gòu)造方法解釋:只有非核心線程,最大線程數(shù)很大(Int.Max(values)),它會為每一個(gè)任務(wù)添加一個(gè)新的線程,這邊有一個(gè)超時(shí)機(jī)制,當(dāng)空閑的線程超過60s內(nèi)沒有用到的話,就會被回收。缺點(diǎn)就是沒有考慮到系統(tǒng)的實(shí)際內(nèi)存大小。

SingleThreadPool 單線程線程池
Executor executor = Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue()));
    }
        private final ExecutorService e;
        DelegatedExecutorService(ExecutorService executor) { e = executor; }

看這個(gè)名字就知道這個(gè)家伙是只有一個(gè)核心線程,底層還進(jìn)行了封裝。但其實(shí)就是只是將線程池的應(yīng)用加了final關(guān)鍵字

ScheduledThreadPool
Executors.newScheduledThreadPool(10);
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

這個(gè)線程池就厲害了,是唯一一個(gè)有延遲執(zhí)行和周期重復(fù)執(zhí)行的線程池。它的核心線程池固定,非核心線程的數(shù)量沒有限制,但是閑置時(shí)會立即會被回收。

線程池最核心方法
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
    }

這個(gè)方法是所有線程池調(diào)用的最底層方法。總共有7個(gè)參數(shù)(面試曾問過參數(shù)的含義)

corePoolSize

核心池的大小,,線程池默認(rèn)創(chuàng)建的線程數(shù)。除非線程池銷毀,否則就不會銷毀

maximumPoolSize

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

keepAliveTime

表示線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會終止。默認(rèn)情況下,只有當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),keepAliveTime才會起作用,直到線程池中的線程數(shù)不大于corePoolSize,即當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),如果一個(gè)線程空閑的時(shí)間達(dá)到keepAliveTime,則會終止,直到線程池中的線程數(shù)不超過corePoolSize。但是如果調(diào)用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數(shù)不大于corePoolSize時(shí),keepAliveTime參數(shù)也會起作用,直到線程池中的線程數(shù)為0;

unit

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

TimeUnit.DAYS; //天

TimeUnit.HOURS; //小時(shí)

TimeUnit.SECONDS; //秒

TimeUnit.MILLISECONDS; //毫秒

TimeUnit.MICROSECONDS; //微妙

TimeUnit.NANOSECONDS; //納秒

workQueue

一個(gè)阻塞隊(duì)列,用來存儲等待執(zhí)行的任務(wù),這個(gè)參數(shù)的選擇也很重要,會對線程池的運(yùn)行過程產(chǎn)生重大影響,一般來說,這里的阻塞隊(duì)列有以下幾種選擇:

ArrayBlockingQueue:基于數(shù)組的先進(jìn)先出隊(duì)列,此隊(duì)列創(chuàng)建時(shí)必須指定大小;

LinkedBlockingQueue:基于鏈表的先進(jìn)先出隊(duì)列,如果創(chuàng)建時(shí)沒有指定此隊(duì)列大小,則默認(rèn)為Integer.MAX_VALUE;

synchronousQueue:這個(gè)隊(duì)列比較特殊,它不會保存提交的任務(wù),而是將直接新建一個(gè)線程來執(zhí)行新來的任務(wù)。

ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。線程池的排隊(duì)策略與BlockingQueue有關(guān)。

threadFactory

線程工廠,主要用來創(chuàng)建線程;

handler

表示當(dāng)拒絕處理任務(wù)時(shí)的策略,有以下四種取值:

ThreadPoolExecutor.AbortPolicy:丟棄任務(wù)并拋出RejectedExecutionException異常。 
ThreadPoolExecutor.DiscardPolicy:也是丟棄任務(wù),但是不拋出異常。 
ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)(重復(fù)此過程)
ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程處理該任務(wù)
線程池家族譜
ExecutorService extend Executor
    AbstractExecutorService implements ExecutorService
    ThreadPoolExecutor extends AbstractExecutorService

Executor是一個(gè)頂層接口,在它里面只聲明了一個(gè)方法execute(Runnable),返回值為void,參數(shù)為Runnable類型,從字面意思可以理解,就是用來執(zhí)行傳進(jìn)去的任務(wù)的;

然后ExecutorService接口繼承了Executor接口,并聲明了一些方法:submit、invokeAll、invokeAny以及shutDown等;

抽象類AbstractExecutorService實(shí)現(xiàn)了ExecutorService接口,基本實(shí)現(xiàn)了ExecutorService中聲明的所有方法;

然后ThreadPoolExecutor繼承了類AbstractExecutorService。

線程池的狀態(tài)
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
 // 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;

值分別是。-1,0,1,2,3,
當(dāng)創(chuàng)建線程池后,初始時(shí),線程池處于RUNNING狀態(tài);

如果調(diào)用了shutdown()方法,則線程池處于SHUTDOWN狀態(tài),此時(shí)線程池不能夠接受新的任務(wù),它會等待所有任務(wù)執(zhí)行完畢;

如果調(diào)用了shutdownNow()方法,則線程池處于STOP狀態(tài),此時(shí)線程池不能接受新的任務(wù),并且會去嘗試終止正在執(zhí)行的任務(wù);

當(dāng)線程池處于SHUTDOWN或STOP狀態(tài),并且所有工作線程已經(jīng)銷毀,任務(wù)緩存隊(duì)列已經(jīng)清空或執(zhí)行結(jié)束后,線程池被設(shè)置為TERMINATED狀態(tài)。

線程池的重要變量
private final BlockingQueue workQueue;              //任務(wù)緩存隊(duì)列,用來存放等待執(zhí)行的任務(wù)
private final ReentrantLock mainLock = new ReentrantLock();   //線程池的主要狀態(tài)鎖,對線程池狀態(tài)(比如線程池大小
                                                              //、runState等)的改變都要使用這個(gè)鎖
private final HashSet workers = new HashSet();  //用來存放工作集
 
private volatile long  keepAliveTime;    //線程存活時(shí)間   
private volatile boolean allowCoreThreadTimeOut;   //是否允許為核心線程設(shè)置存活時(shí)間
private volatile int   corePoolSize;     //核心池的大小(即線程池中的線程數(shù)目大于這個(gè)參數(shù)時(shí),提交的任務(wù)會被放進(jìn)任務(wù)緩存隊(duì)列)
private volatile int   maximumPoolSize;   //線程池最大能容忍的線程數(shù)
 
private volatile int   poolSize;       //線程池中當(dāng)前的線程數(shù)
 
private volatile RejectedExecutionHandler handler; //任務(wù)拒絕策略
 
private volatile ThreadFactory threadFactory;   //線程工廠,用來創(chuàng)建線程
 
private int largestPoolSize;   //用來記錄線程池中曾經(jīng)出現(xiàn)過的最大線程數(shù)
 
private long completedTaskCount;   //用來記錄已經(jīng)執(zhí)行完畢的任務(wù)個(gè)數(shù)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/69579.html

相關(guān)文章

  • 后端ing

    摘要:當(dāng)活動線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會根據(jù)來進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...

    roadtogeek 評論0 收藏0
  • 使用 Executors,ThreadPoolExecutor,創(chuàng)建線程源碼分析理解

    摘要:源碼分析創(chuàng)建可緩沖的線程池。源碼分析使用創(chuàng)建線程池源碼分析的構(gòu)造函數(shù)構(gòu)造函數(shù)參數(shù)核心線程數(shù)大小,當(dāng)線程數(shù),會創(chuàng)建線程執(zhí)行最大線程數(shù),當(dāng)線程數(shù)的時(shí)候,會把放入中保持存活時(shí)間,當(dāng)線程數(shù)大于的空閑線程能保持的最大時(shí)間。 之前創(chuàng)建線程的時(shí)候都是用的 newCachedThreadPoo,newFixedThreadPool,newScheduledThreadPool,newSingleThr...

    Chiclaim 評論0 收藏0
  • Python線程源碼分析

    摘要:對線程池的研究是之前對分析的附加工作。在之前對源碼分析的文章中,寫到調(diào)度器將任務(wù)放入線程池的函數(shù)這里分析的線程池類是,也就是上述代碼中所使用的類。 對Python線程池的研究是之前對Apshceduler分析的附加工作。 在之前對Apshceduler源碼分析的文章中,寫到調(diào)度器將任務(wù)放入線程池的函數(shù) def _do_submit_job(self, job, run_time...

    ephererid 評論0 收藏0
  • 一看就懂的Java線程分析詳解

    摘要:任務(wù)性質(zhì)不同的任務(wù)可以用不同規(guī)模的線程池分開處理。線程池在運(yùn)行過程中已完成的任務(wù)數(shù)量。如等于線程池的最大大小,則表示線程池曾經(jīng)滿了。線程池的線程數(shù)量。獲取活動的線程數(shù)。通過擴(kuò)展線程池進(jìn)行監(jiān)控??蚣馨ň€程池,,,,,,等。 Java線程池 [toc] 什么是線程池 線程池就是有N個(gè)子線程共同在運(yùn)行的線程組合。 舉個(gè)容易理解的例子:有個(gè)線程組合(即線程池,咱可以比喻為一個(gè)公司),里面有3...

    Yangder 評論0 收藏0
  • Java ThreadPoolExecutor 線程源碼分析

    摘要:線程池常見實(shí)現(xiàn)線程池一般包含三個(gè)主要部分調(diào)度器決定由哪個(gè)線程來執(zhí)行任務(wù)執(zhí)行任務(wù)所能夠的最大耗時(shí)等線程隊(duì)列存放并管理著一系列線程這些線程都處于阻塞狀態(tài)或休眠狀態(tài)任務(wù)隊(duì)列存放著用戶提交的需要被執(zhí)行的任務(wù)一般任務(wù)的執(zhí)行的即先提交的任務(wù)先被執(zhí)行調(diào)度 線程池常見實(shí)現(xiàn) 線程池一般包含三個(gè)主要部分: 調(diào)度器: 決定由哪個(gè)線程來執(zhí)行任務(wù), 執(zhí)行任務(wù)所能夠的最大耗時(shí)等 線程隊(duì)列: 存放并管理著一系列線...

    greatwhole 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<