美團面試官問Java 線程池,這樣的回答讓他豎起了大拇指!

做者:天才程序YUAN」

原文:https://blog.csdn.net/JAck_chen0309/article/details/105250643java

前言

這周我投遞出了簡歷,崗位是java後端開發工程師。這周美團面試官給我進行了面試。面試過程當中他問了線程池,今天詳細講一講Java 線程池。

線程池

線程池維護着多個線程,等待着監督管理者分配可併發執行的任務。這避免了在處理短期任務時建立與銷燬線程的代價。
start()建立必定數量的線程池,進行線程循環

stop()中止全部線程循環,回收全部資源

addTask()添加任務複製代碼
Excutors建立線程池便捷方法以下:
Executors.newFixedThreadPool(100);//建立固定大小的線程池
Executors.newSingleThreadExecutor();//建立只有一個線程的線程池
Executors.newCachedThreadPool();//建立一個不限線程數上限的線程池,任何提交的任務都將當即執行複製代碼
對於服務端須要長期運行的程序,建立線程池應該使用ThreadPoolExecutor的構造方法
public ThreadPoolExecutor(
      int corePoolPoolSize,//線程池長期維持的線程數
      int maximumPoolSize, //線程數的上限
      long keepAliveTime,//空閒線程存活時間
      TimeUnit unit,//時間單位
      BlockingQueue<Runnable> workQueue,//任務的排隊隊列
      ThreadFactory threadFactory,//新線程的產生方式
      RejectedExecutionHandler handler//拒絕策略
  )複製代碼
java線程池有7大參數,4大特性。
特性一:當池中正在運行的線程數(包括空閒線程)小於corePoolSize時,新建線程執行任務。
特性二:當池中正在運行的線程數大於等於corePoolSize時,新插入的任務進入workQueue排隊(若是workQueue長度容許),等待空閒線程來執行。
特性三:當隊列裏的任務數達到上限,而且池中正在運行的線程數小於maximumPoolSize,對於新加入的任務,新建線程。
特性四:當隊列裏的任務數達到上限,而且池中正在運行的線程數等於maximumPoolSize,對於新加入的任務,執行拒絕策略(線程池默認的拒絕策略是拋異常)。

種類

一、newCachedThreadPool

核心線程數爲0,最大線程數爲 Integer.MAX_VALUE
public static ExecutorService newCachedThreadPool() {
	return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
	                                      60L, TimeUnit.SECONDS,
	                                      new SynchronousQueue<Runnable>());
}
複製代碼
1.1做用
建立一個可根據須要建立新線程的線程池,可是在之前構造的線程可用時將重用它們,並在須要時使用提供的 ThreadFactory 建立新線程。
1.2特徵
(1)線程池中數量沒有固定,可達到最大值(Interger. MAX_VALUE)
(2)線程池中的線程可進行緩存重複利用和回收(回收默認時間爲1分鐘)
(3)當線程池中,沒有可用線程,會從新建立一個線程
1.3建立方式
Executors.newCachedThreadPool();

二、newFixedThreadPool

核心線程數與最大線程數均爲指定的nThreads
空閒線程的存活時間是0
工做隊列是無界隊列
public static ExecutorService newFixedThreadPool(int nThreads) {
	return new ThreadPoolExecutor(nThreads, nThreads,
	                                      0L, TimeUnit.MILLISECONDS,
	                                      new LinkedBlockingQueue<Runnable>());
}
複製代碼
2.1做用
建立一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程。在任意點,在大多數 nThreads 線程會處於處理任務的活動狀態。若是在全部線程處於活動狀態時提交附加任務,則在有可用線程以前,附加任務將在隊列中等待。若是在關閉前的執行期間因爲失敗而致使任何線程終止,那麼一個新線程將代替它執行後續的任務(若是須要)。在某個線程被顯式地關閉以前,池中的線程將一直存在。
2.2特徵
(1)線程池中的線程處於必定的量,能夠很好的控制線程的併發量
(2)線程能夠重複被使用,在顯示關閉以前,都將一直存在
(3)超出必定量的線程被提交時候需在隊列中等待
2.3建立方式
(1)Executors.newFixedThreadPool(int nThreads);//nThreads爲線程的數量 
(2)Executors.newFixedThreadPool(int nThreads,ThreadFactory threadFactory);//nThreads爲線程的數量,threadFactory建立線程的工廠方式複製代碼

三、newSingleThreadExecutor

核心線程數與最大線程數均爲1
工做隊列是無界隊列
public static ExecutorService newSingleThreadExecutor() {
	return new FinalizableDelegatedExecutorService
	            (new ThreadPoolExecutor(1, 1,
	                                    0L, TimeUnit.MILLISECONDS,
	                                    new LinkedBlockingQueue<Runnable>()));
}
複製代碼
3.1做用
建立一個使用單個 worker 線程的 Executor,以無界隊列方式來運行該線程。(注意,若是由於在關閉前的執行期間出現失敗而終止了此單個線程,那麼若是須要,一個新線程將代替它執行後續的任務)。可保證順序地執行各個任務,而且在任意給定的時間不會有多個線程是活動的。與其餘等效的 newFixedThreadPool(1) 不一樣,可保證無需從新配置此方法所返回的執行程序便可使用其餘的線程。
3.2特徵
線程池中最多執行1個線程,以後提交的線程活動將會排在隊列中以此執行。
3.3建立方式
(1)Executors.newSingleThreadExecutor() ; 
(2)Executors.newSingleThreadExecutor(ThreadFactory threadFactory);// threadFactory建立線程的工廠方式複製代碼

四、newScheduledThreadPool

指定核心線程數corePoolSize
最大線程數是Integer.MAX_VALUE
DelayedWorkQueue:任務隊列會根據任務延時時間的優先級進行執行

public class ScheduledThreadPoolExecutor
        extends ThreadPoolExecutor
        implements ScheduledExecutorService {
	....................
	/**
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
     * given core pool size.
     *
     * @param corePoolSize the number of threads to keep in the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     */
	public ScheduledThreadPoolExecutor(int corePoolSize) {
		super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
		              new DelayedWorkQueue());
	}
複製代碼

4.1做用
建立一個線程池,它可安排在給定延遲後運行命令或者按期地執行。
4.2特徵
(1)線程池中具備指定數量的線程,即使是空線程也將保留
(2)可定時或者延遲執行線程活動
4.3建立方式
(1)Executors.newScheduledThreadPool(int corePoolSize);// corePoolSize線程的個數 
(2)newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);// corePoolSize線程的個數,threadFactory建立線程的工廠複製代碼

五、newSingleThreadScheduledExecutor

5.1做用
建立一個單線程執行程序,它可安排在給定延遲後運行命令或者按期地執行。
5.2特徵
(1)線程池中最多執行1個線程,以後提交的線程活動將會排在隊列中以此執行
(2)可定時或者延遲執行線程活動
5.3建立方式
(1)Executors.newSingleThreadScheduledExecutor() ; 
(2)Executors.newSingleThreadScheduledExecutor(ThreadFactory threadFactory);//threadFactory建立線程的工廠複製代碼

工做隊列

SynchronousQueue:直接提交

是工做隊列的默認選項,將任務直接提交給線程而不保持。
若是不存在可用於當即運行任務的線程,則試圖把任務加入隊列將失敗,所以會構造一個新的線程。
優缺點
優勢:能夠避免在處理可能具備內部依賴性的請求集時出現鎖。
直接提交一般要求無界maximumPoolSizes 以免拒絕新提交的任務。
當命令以超過隊列所能處理的平均數連續到達時,此策略容許無界線程具備增加的可能性。

ArrayBlockingQueue:無界隊列

在全部核心線程都忙時,新任務在隊列中等待。
所以,僅建立corePoolSize線程便可。(maximumPoolSize的值沒有任何做用。)
當每一個任務徹底獨立於其餘任務時,所以任務不會影響彼此的執行。
優缺點
優勢:例如,在網頁服務器中,儘管這種排隊方式對於消除短暫的突發請求頗有用。
缺點:當命令請求到達速度比其處理速度更快時,工做隊列無限制增加。

LinkedBlockingQueue:有界隊列

當與有限的maximumPoolSizes一塊兒使用時,有界隊列有助於防止資源耗盡,可是調整和控制起來會更加困難。
隊列大小和最大池大小能夠相互權衡
使用大隊列和小池能夠最大程度地減小CPU使用率,操做系統資源和上下文切換開銷,但可能致使人爲地下降吞吐量。
若是任務頻繁阻塞(例如若是它們是受I/O約束的),則系統可能能夠爲非預約的更多線程安排時間。
使用小隊列一般須要更大的池大小,這會使CPU繁忙,但可能會遇到不可接受的調度開銷,這也會下降吞吐量。

拒絕策略

AbortPolicy:處理程序遭到拒絕將拋出運行時 RejectedExecutionException

DiscardPolicy:不能執行的任務將被刪除程序員

DiscardOldestPolicy:若是執行程序還沒有關閉,則位於工做隊列頭部的任務將被刪除,而後重試執行程序(若是再次失敗,則重複此過程)面試

CallerRunsPolicy:線程調用運行該任務的 execute 自己。此策略提供簡單的反饋控制機制,可以減緩新任務的提交速度。算法

RejectedExecutionHandler rejected = null;
rejected = new ThreadPoolExecutor.AbortPolicy();//默認,隊列滿了丟任務拋出異常
rejected = new ThreadPoolExecutor.DiscardPolicy();//隊列滿了丟任務不異常
rejected = new ThreadPoolExecutor.DiscardOldestPolicy();//將最先進入隊列的任務刪,以後再嘗試加入隊列
rejected = new ThreadPoolExecutor.CallerRunsPolicy();//若是添加到線程池失敗,那麼主線程會本身去執行該任務複製代碼

總結

我們玩歸玩,鬧歸鬧,別拿面試開玩笑。
線程池記憶口訣:七個參數,四大特性,五個種類、三大工做隊列、四大拒絕策略
線程池,在面試中出現的次數很是多,你們面試前要把知識點記牢。

最後

歡迎關注公衆號:程序員追風,領取一線大廠Java面試題總結+各知識點學習思惟導+一份300頁pdf文檔的Java核心知識點總結!spring

這些資料的內容都是面試時面試官必問的知識點,篇章包括了不少知識點,其中包括了有基礎知識、Java集合、JVM、多線程併發、spring原理、微服務、Netty 與RPC 、Kafka、日記、設計模式、Java算法、數據庫、Zookeeper、分佈式緩存、數據結構等等。數據庫

相關文章
相關標籤/搜索