摘要:創建一個線程池,具有固定線程數,運行在共享的無界隊列中。固定線程數源碼如下是的實現類。線程池中允許最大的線程數。如果線程數超過了核心線程數,過量的線程在關閉前等待新任務的最大時間。處理因為線程邊界和隊列容量導致的堵塞。
1.Executors.newFixedThreadPool(int nThreads):創建一個線程池,具有固定線程數,運行在共享的無界隊列中。在大多數時候,線程會主動執行任務,當所有的線程都在執行任務時,有新的任務加入進來,就會進入等待隊列(可以有源源不斷的任務加入進來,因為是無界隊列),當有空閑的線程,等待隊列中的任務就會被執行。如果有線程在執行過程中因為執行失敗要關閉,新創建的線程會替失敗的線程執行接下來的任務。如果想要關閉這個線程池,可以調用ExecutorService的shutDown方法。
nThreads 固定線程數
源碼如下:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
2.ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue
corePoolSize 核心線程數,即使是空閑的時候,線程池中也會保留線程的數量。如果設置allowCoreThreadTimeOut為true,會使用keepAliveTime作為等待工作時間,默認為false。
maximumPoolSize 線程池中允許最大的線程數。
keepAliveTime 如果線程數超過了核心線程數,過量的線程在關閉前等待新任務的最大時間。
unit keepAliveTime 參數的時間單元。
workQueue 用來存放等待執行的任務,這些任務是通過execute方法提交的Runnable任務。
源碼如下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
3.ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue
threadFactory 用來創建新線程的工廠。
handler 處理因為線程邊界和隊列容量導致的堵塞。
源碼如下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, 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.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
4.LinkedBlockingQueue:Executors.newFixedThreadPool()使用基于鏈表結點的無界隊列LinkedBlockingQueue存儲待執行的任務。繼承了AbstractQueue類,實現了BlockingQueue接口,采用先進先出的排列方式,頭結點是入隊時間最長的元素,尾結點是入隊時間最短的元素。新結點添加到隊尾,從隊頭彈出結點。鏈表隊列的特點是:跟基于數組的隊列相比有更大的吞吐量,但在大多并發應用中性能會比較差。LinkedBlockingQueue可以在創建的時候傳遞一個容量參數,限制隊列的長度,不設定的情況下,默認是Integer.MAX_VALUE。在沒有超過隊列邊界的情況下,每次添加會自動創建鏈表結點。
源碼如下:
public LinkedBlockingQueue() { this(Integer.MAX_VALUE); }
public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node(null); }
5.DefaultThreadFactory:返回默認的線程工廠創建新線程。執行器Executor在同一個線程組中創建所有新的線程。如果存在SecurityManager,就使用SecurityManager的線程組,否則使用當前線程的線程組。每一個新創建的線程作為非守護線程,其優先級設置為Thread.NORM_PRIORITY和線程組允許的最大優先級的較小者。可以通過Thread.getName()獲取線程的名稱,形式如:pool-N-thread-M,N表示線程工廠的序列號,M表示線程工廠創建的線程的序列號。
源碼如下:
public static ThreadFactory defaultThreadFactory() { return new DefaultThreadFactory(); }
static class DefaultThreadFactory implements ThreadFactory { private static final AtomicInteger poolNumber = new AtomicInteger(1); private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; } ...... }
6.AbortPolicy:默認的拒絕執行處理器。拋出一個RejectedExecutionException。
源碼如下:
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
public static class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }
7.例子
@Test public void testFixedDemo01() { ExecutorService executorService = Executors.newFixedThreadPool(4); for(int i = 0;i < 10;i++) { executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " " +" 走啦"); } }); } }
運行結果:
核心線程數和最大線程數都是4,創建了一個線程工廠。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71077.html
摘要:的前位數用來表示線程的數量,后面三位用來表示線程池的狀態。線程池的狀態有五種,分別是,根據單詞就能猜出大概。并且為了考慮性能問題,線程池的設計沒有使用悲觀鎖關鍵字,而是大量使用了和機制。 零 前期準備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 2 ThreadPoolExecutor ...
摘要:創建方法最大線程數即源碼單線程化的線程池有且僅有一個工作線程執行任務所有任務按照指定順序執行,即遵循隊列的入隊出隊規則創建方法源碼還有一個結合了和,就不介紹了,基本不用。 *本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家發布 為什么用線程池 創建/銷毀線程伴隨著系統開銷,過于頻繁的創建/銷毀線程,會很大程度上影響處理效率 >例如: > >記創建線程消耗時間T1,執行...
摘要:在前面介紹的文章中,提到了關于線程池的創建介紹,在文章之系列外部中第一部分有詳細的說明,請參閱文章中其實說明了外部的使用方式,但是沒有說內部是如何實現的,為了加深對實現的理解,在使用中可以放心,我們這里將做源碼解析以及反饋到原理上,工具可 在前面介紹JUC的文章中,提到了關于線程池Execotors的創建介紹,在文章:《java之JUC系列-外部Tools》中第一部分有詳細的說明,請參...
摘要:去美團面試,問到了什么是線程池,如何使用,為什么要用以下做個總結。二線程池線程池的作用線程池作用就是限制系統中執行線程的數量。真正的線程池接口是。創建固定大小的線程池。此線程池支持定時以及周期性執行任務的需求。 去美團面試,問到了什么是線程池,如何使用,為什么要用,以下做個總結。關于線程之前也寫過一篇文章《高級面試題總結—線程池還能這么玩?》 1、什么是線程池:? java.util...
閱讀 994·2023-04-25 15:42
閱讀 3584·2021-11-02 14:38
閱讀 2886·2021-09-30 09:48
閱讀 1420·2021-09-23 11:22
閱讀 3379·2021-09-06 15:02
閱讀 3186·2021-09-04 16:41
閱讀 607·2021-09-02 15:41
閱讀 2012·2021-08-26 14:13