摘要:線程池的作用線程池能有效的處理多個(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)鍵字
ScheduledThreadPoolExecutors.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, BlockingQueueworkQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); }
這個(gè)方法是所有線程池調(diào)用的最底層方法。總共有7個(gè)參數(shù)(面試曾問過參數(shù)的含義)
核心池的大小,,線程池默認(rèn)創(chuàng)建的線程數(shù)。除非線程池銷毀,否則就不會銷毀
線程池最大線程數(shù),它表示在線程池中最多能創(chuàng)建多少個(gè)線程;
表示線程沒有任務(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;
參數(shù)keepAliveTime的時(shí)間單位,有7種取值,在TimeUnit類中有7種靜態(tài)屬性:
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小時(shí)
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //納秒
一個(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)。
線程工廠,主要用來創(chuàng)建線程;
表示當(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 BlockingQueueworkQueue; //任務(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
摘要:當(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...
摘要:源碼分析創(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...
摘要:對線程池的研究是之前對分析的附加工作。在之前對源碼分析的文章中,寫到調(diào)度器將任務(wù)放入線程池的函數(shù)這里分析的線程池類是,也就是上述代碼中所使用的類。 對Python線程池的研究是之前對Apshceduler分析的附加工作。 在之前對Apshceduler源碼分析的文章中,寫到調(diào)度器將任務(wù)放入線程池的函數(shù) def _do_submit_job(self, job, run_time...
摘要:任務(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...
摘要:線程池常見實(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ì)列: 存放并管理著一系列線...
閱讀 1828·2023-04-26 02:32
閱讀 576·2021-11-18 13:12
閱讀 2459·2021-10-20 13:48
閱讀 2528·2021-10-14 09:43
閱讀 3840·2021-10-11 10:58
閱讀 3516·2021-09-30 10:00
閱讀 2943·2019-08-30 15:53
閱讀 3496·2019-08-30 15:53