執行緒學習三:執行緒池ThreadPoolExecutor 與 Executors
/** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set * @param maximumPoolSize the maximum number of threads to allow in the * pool * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. * @param unit the time unit for the {@code keepAliveTime} argument * @param workQueue the queue to use for holding tasks before they are * executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method. * @param threadFactory the factory to use when the executor * creates a new thread * @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached * @throws IllegalArgumentException if one of the following holds:<br> * {@code corePoolSize < 0}<br> * {@code keepAliveTime < 0}<br> * {@code maximumPoolSize <= 0}<br> * {@code maximumPoolSize < corePoolSize} * @throws NullPointerException if {@code workQueue} * or {@code threadFactory} or {@code handler} is null */ 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; } <pre name="code" class="java">/** * Set containing all worker threads in pool. Accessed only when * holding mainLock. */ private final HashSet<Worker> workers = new HashSet<Worker>();
ThreadPoolExecutor 類的邏輯處理集中在8個屬性上面,上面是8個屬性構造原始碼
workers : 執行緒池 ,Worker是其內部類,沒個Worder含有一個執行緒
corePoolSize : 執行緒池中最小活動執行緒
maximumPoolSize : 執行緒池中最大允許執行緒數
workQueue : 快取佇列
keepAliveTime : 執行緒池中空閒執行緒最大存活時間
TimeUnit : keepAliveTime的單位
threadFactory : 新建執行緒時工廠類
handle : 處理被拒絕執行緒的處理類
執行過程,如我們上篇的圖,也如上面原始碼中的英文註釋 (至於執行原始碼,有點地方還沒弄通,就不寫分析了)
當新來任務的時候,
1、如果執行緒池小於corePoolSize , 那麼新建執行緒執行該任務
2、如果執行緒池大於等於corePoolSize , 那麼就往workQueue中新增
3、如果workQueue滿了且執行緒池小於maximumPoolSize ,那麼就新建執行緒執行任務
4、如果workQueue滿了且執行緒池等於maximumPoolSize ,那麼就拒絕任務 。
至於快取中的執行緒是如何執行的呢 ?
在每個新建執行緒中都有這麼一段等效程式碼 加在原任務執行結束後:
while( task = workQueue.poll(keepAliveTime ,TimeUnit ) ) {task.run();}
即執行緒執行任務完後會最大阻塞等待keepAliveTime 時間,直到從快取佇列workQueue中獲取任務 (這段時間內稱執行緒為閒置執行緒)。
獲取到新任務就執行,沒獲取到,那麼執行緒結束。
至於常見的Executors中的幾個構建物件原始碼如下,大家自己理解嘍:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}//無限快取,有nThreads個執行緒能夠併發執行任務,閒置時間為0 ,即執行完任務瞬間找不到新任務就關閉執行緒
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
} //無限快取,只有一個執行緒順訊的執行放進來的任務,閒置時間為0,即執行完任務瞬間找不到新任務就關閉執行緒
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
} //0快取,每新來個任務都看是否有閒置執行緒,有就使用閒置執行緒執行,否則新建執行緒 。 執行緒最大閒置時間60s
一般情況上訴3個已經滿足,如果大家另有需求就自行構建嘍 。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(5, 10,
1L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5)));
}
相關推薦
執行緒學習三:執行緒池ThreadPoolExecutor 與 Executors
/** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param corePoolSize the
java執行緒學習(三):執行緒中斷 interrupt() 方法的使用
上一章節中,我們對執行緒終止stop方法進行了講解,stop終止執行緒的方法已經被丟棄,原因是執行緒的終止太暴力,會導致不必要的資料錯誤,所以stop方法在不自信的情況下,慎用慎用。。。。同時,也提供了較為完善的終止方案了。 本節就來學習執行緒中斷 interrupt() 方法的使用: 一、
執行緒學習二:執行緒池執行Runnable與Callable
1、瞭解執行緒池幾個類之間的關係 (結合圖看後面的分析) FutureTask 繼承 RunnableFuture , RunnableFuture 實現介面 Runnable 2、分析常用呼叫執行緒池程式碼(以下稱為程式碼A)
java執行緒學習(四):執行緒等待wait()和通知notify()的詳細使用
執行緒等待wait()和通知notify(),主要用於多執行緒之間的協作,而且這兩個方法都是屬於Object類,說明任何物件都可以呼叫這兩個方法。 當在一個物件例項上呼叫wait()方法後,當前執行緒就會在這個物件上等待。直到另外的執行緒呼叫了notify()方法,出於等待的執行緒才得以
Java執行緒學習(一):執行緒安全與不安全
作為一個Java web開發人員,很少也不需要去處理執行緒,因為伺服器已經幫我們處理好了。記得大一剛學Java的時候,老師帶著我們做了一個區域網聊天室,用到了AWT、Socket、多執行緒、I/O,編寫的客戶端和伺服器,當時做出來很興奮,回學校給同學們演示,感覺自己好NB
C++11併發學習之三:執行緒同步
1.<mutex> 標頭檔案介紹 (1)Mutex系列類(四種) std::mutex,最基本的 Mutex 類。 std::recursive_mutex,遞迴 Mutex 類。 std::time_mutex,定時 Mutex 類。 std::recursive_ti
《Java高併發程式設計》學習 --3.2 執行緒複用:執行緒池
1)什麼是執行緒池 為了避免系統頻繁地建立和銷燬執行緒,我們可以讓建立的執行緒進行復用。執行緒池中,總有那麼幾個活躍執行緒。當你需要使用執行緒時,可以從池子中隨便拿一個空閒執行緒,當完成工作時,並不急著關閉執行緒,而是將整個執行緒退回到池子,方便其他人使用。 2)JDK對執
java執行緒學習(八):多執行緒高階使用之執行緒池的使用(非常推薦,涉及:ThreadPoolExecutor,Executors,ThreadPoolExecutor,ScheduledThreadP)
前言: 通過前面幾篇文章的學習,對多執行緒的知識瞭解了很多,同時也明白,其實學習不僅僅要看書,看文章,還要自己動手去敲demo,順便寫點文章收穫更多。當然多執行緒如果僅僅是用前面幾篇的知識的話,那未免也太膚淺了,畢竟,執行緒如果頻繁開啟和關閉的話,對系統資源的消耗那是相當大的。所以,
java併發包學習系列:執行緒複用之執行緒池
什麼是執行緒池 頻繁使用new Thread來建立執行緒的方式並不太好。因為每次new Thread新建和銷燬物件效能較差,執行緒缺乏統一管理。好在Java提供了執行緒池,它能夠有效的管理、排程執行緒,避免過多的資源消耗。優點如下: 重用存在的執行緒,減少物
Java多執行緒三:執行緒池和Executors類解析
執行緒池 多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。 假設一個伺服器完成一項任務所需時間為:T1 建立執行緒時間,T2 線上程中執行任務的時間,T3 銷燬執行緒時間。 如果:T1 +
Java併發包原始碼學習系列:執行緒池ThreadPoolExecutor原始碼解析
[toc] 系列傳送門: - [Java併發包原始碼學習系列:AbstractQueuedSynchronizer](https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/112254373) - [Java併發包原始碼學習系列:CLH同步佇列及同步資源
Java併發包原始碼學習系列:執行緒池ScheduledThreadPoolExecutor原始碼解析
[toc] ## ScheduledThreadPoolExecutor概述 我們在上一篇學習了ThreadPoolExecutor的實現原理:[Java併發包原始碼學習系列:執行緒池ThreadPoolExecutor原始碼解析](https://blog.csdn.net/Sky_QiaoBa_Sum
JDK併發包-執行緒複用:執行緒池
為了避免系統頻繁地建立和銷燬執行緒,我們可以讓建立的執行緒進行復用。執行緒池中,總有那麼幾個活躍執行緒。當你需要使用執行緒時,可以從池子中隨便拿一個空閒執行緒,當完成工作時,並不急著關閉執行緒,而是將整個執行緒退回到池子,方便其他人使用。 1.1 JDK對執行緒池的支援 JDK提供一
多執行緒學習筆記二--執行緒池
使用執行緒池的兩種方式:Runable介面和Callable介面 1.Runable介面實現步驟: 建立執行緒池物件 建立Runnable介面實現類 提交Runable介面實現類 關閉執行緒池(實際使用時一般不關閉,因為使用執行緒池就是為了減少執行緒的建立和銷燬)
Python並行程式設計(三):執行緒同步Lock
1、基礎概念 當兩個或以上對共享記憶體操作的併發執行緒中,如果有一個改變資料,又沒有同步機制的條件下,就會產生競爭條件,可能會導致執行無效程式碼、bug等異常行為。 競爭條件最簡單的解決方法是使用鎖。鎖的操作非常簡單,當一個執行緒需要訪問部分共享記憶體時,它必須先獲得鎖才能訪問。此執
java執行緒學習(二): 終止執行緒講解:Stop()方法(後附如何正確終止執行緒)
本章來學習Java的stop執行緒終止方法; 老規矩,先看原始碼: @Deprecated public final void stop() { SecurityManager var1 = System.getSecurityManager(); if (var1 != n
多執行緒學習六:Future與FutureTask
FutureTask是Future介面的一個唯一實現類,可以作為Runnable被執行緒執行,也可以作為Future得到Callable的返回值。 Future就是對於具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果。必要
Java執行緒(三):執行緒協作-生產者/消費者問題
上一篇講述了執行緒的互斥(同步),但是在很多情況下,僅僅同步是不夠的,還需要執行緒與執行緒協作(通訊),生產者/消費者問題是一個經典的執行緒同步以及通訊的案例。該問題描述了兩個共享固定大小緩衝區的執行緒,即所謂的“生產者”和“消費者”在實際執行時會發生的問題。
java執行緒學習(三)----死鎖(面試常見)
延遲載入的單例多執行緒設計模式(懶漢式) 單例模式 是讓呼叫者只產生一個唯一的物件。 分為餓漢式和懶漢式 餓漢式: class EHan{ private static final EHan e = new EHan(); publi
java執行緒學習(九):阻塞佇列BlockingQueue講解
上一章中學到了執行緒池的詳細使用以及核心執行緒池的部分原始碼,其中就包含有BlockingQueue的資訊,那麼到底BlockingQueue是什麼呢,有什麼用呢,本章就是學這個的。 Blocking翻譯過來為’阻塞’,Queue就是佇列的意思,那麼BlockingQueue就是阻塞隊列了,