??11月6號的北京軟考取消了,不想別的了,繼續開卷!!!!!!每周2-3篇,中間穿插面試真題分享,
??大家好,我是陳哈哈,北漂五年,相信大家和我一樣,都有一個大廠夢,作為一名資深Java選手,深知面試重要性,接下來我準備用100天時間,基于Java崗面試中的高頻面試題,以每日3題的形式,帶你過一遍熱門面試題及恰如其分的解答,
??一路走來,隨著問題加深,發現不會的也愈來愈多,但底氣著實足了不少,相信不少朋友和我一樣,榷訓月累才是最有效的學習方式!想起高三時一個同學的座右銘:只有沉下去,才能浮上來,共勉(juan),

作者:爪哇小白2021 —— 博客地址
車票
- 面試題1:說一下執行緒池都是怎么創建的?
- 追問1:執行緒池都有哪些引數?
- 追問2:執行緒池都有哪幾種作業佇列(WorkQueue)?分別有什么特點?
- 面試題2:執行緒池提交一個任務經過哪些步驟?
- 追問1:執行緒池的拒絕策略了解么?
- 面試題3:關閉執行緒池的方式都有哪些?
- 每日小結
??本欄目Java開發崗高頻面試題主要出自以下各技術堆疊:Java基礎知識、集合容器、并發編程、JVM、Spring全家桶、MyBatis等ORMapping框架、MySQL資料庫、Redis快取、RabbitMQ訊息佇列、Linux操作技巧等,
??在《阿里Java開發代碼規范》中表示,
執行緒資源必須通過執行緒池提供,不允許在應用中自行顯式創建執行緒,即在使用多執行緒時,均要通過執行緒池創建,

面試題1:說一下執行緒池都是怎么創建的?
執行緒池可以自動創建也可以手動創建,
自動創建執行緒池
??自動創建體現在Executors工具類中,常見的可以創建newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool;
public static ExecutorService newFixedThreadPool(int var0) {
return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}
public static ExecutorService newSingleThreadExecutor() {
return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
}
public static ScheduledExecutorService newScheduledThreadPool(int var0) {
return new ScheduledThreadPoolExecutor(var0);
}
手動創建執行緒池(推薦)
??手動創建體現在可以靈活設定執行緒池的各個引數,體現在代碼中即ThreadPoolExecutor類構造器上各個實參的不同:
/**
* @Description 配置執行緒池實體,用于呼叫
*/
@Configuration
public class ThreadPoolConfig {
@Bean(value = "threadPoolInstance")
public ExecutorService createThreadPoolInstance() {
//通過guava類別庫的ThreadFactoryBuilder來實作執行緒工廠類并設定執行緒名稱
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build();
ExecutorService threadPool = new ThreadPoolExecutor(10, 16, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
return threadPool;
}
}
//通過name=threadPoolInstance參考執行緒池實體
@Resource(name = "threadPoolInstance")
private ExecutorService executorService;
@Override
public void spikeConsumer() {
// 執行緒池啟動執行緒
executorService.execute(new Runnable() {
@Override
public void run() {
// 可執行代碼塊兒
}});
}
??在《阿里Java開發代碼規范》中表示,實際專案開發中推薦使用手動創建執行緒池的方式,而不用默認自動創建方式;

追問1:執行緒池都有哪些引數?
// 默認拒絕策略為 AbortPolicy
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
corePoolSize:核心執行緒數,也是執行緒池中常駐的執行緒數,執行緒池初始化時默認是沒有執行緒的,當任務來臨時才開始創建執行緒去執行任務maximumPoolSize:最大執行緒數,在核心執行緒數的基礎上可能會額外增加一些非核心執行緒,需要注意的是只有當workQueue佇列填滿時才會創建多于corePoolSize的執行緒(執行緒池總執行緒數不超過maxPoolSize)keepAliveTime:非核心執行緒的空閑時間超過keepAliveTime就會被自動終止回收掉,注意當corePoolSize=maxPoolSize時,keepAliveTime引數也就不起作用了(因為不存在非核心執行緒);- unit:keepAliveTime的
時間單位 workQueue:用于保存任務的佇列,可以為無界、有界、同步移交三種佇列型別之一,當池子里的作業執行緒數大于corePoolSize時,這時新進來的任務會被放到佇列中threadFactory:創建執行緒的工廠類,默認使用Executors.defaultThreadFactory(),也可以使用guava庫的ThreadFactoryBuilder來創建handler:執行緒池無法繼續接收任務(佇列已滿且執行緒數達到maximunPoolSize)時的飽和策略,取值有AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy
// 默認拒絕策略為 AbortPolicy
ExecutorService threadPool = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
追問2:執行緒池都有哪幾種作業佇列(WorkQueue)?分別有什么特點?
常用
ArrayBlockintQueue(有界佇列):基于陣列的有限阻塞佇列,先進先出(FIFO),插入資料和取出資料公用一個鎖物件;LinkedBlockingQueue(無界佇列):基于鏈表的無限阻塞佇列,先進先出(FIFO),當請求越來越多時(任務處理速度跟不上任務提交速度造成請求堆積)可能導致記憶體占用過多或OOM,newFixedThreadPool 和 newSingleThreadExecutor 使用這個佇列;SynchronousQueue(同步移交佇列):不存盤元素的阻塞佇列,插入操作必須等待一個執行緒呼叫移除操作,否則一直會阻塞,newCachedTHreadPool 使用這個佇列
不常用
- PriorityBlockingQueue:有優先級的無限阻塞佇列,基于最小二叉堆實作
- DelayedWorkQueue:每個元素指定延時時間,只有當時間到了才能從佇列中獲取該元素,是一個無限佇列,

課間休息,又來秀一下來自咱們群里同學的搬磚工地,坐標:深圳,美啊,
作者:胡巴
面試題2:執行緒池提交一個任務經過哪些步驟?

執行緒池提交任務流程為:
- 當執行緒池新加入一個執行緒時,首先判斷當前執行緒數,是否小于
corePoolSize(核心執行緒數),如果小于,則執行步驟2,否則執行3; - 創建新執行緒添加到執行緒池中,流程結束;
- 判斷當前執行緒池等待佇列是否已滿,若已滿,則跳轉至步驟5;
- 加入等待佇列,等待執行緒池空閑,流程結束;
- 判斷當前執行緒數是否已達到
maximumPoolSize(最大執行緒數),若未達到,則跳轉至步驟7; - 執行執行緒池拒絕策略,流程結束;
- 創建一個新執行緒,執行任務;
- 流程結束;
??比如現有一個執行緒池,corePoolSize=10,maxPoolSize=20,佇列長度為100,那么當任務過來會先創建10個核心執行緒數,接下來進來的任務會進入到佇列中直到佇列滿了,會創建額外的執行緒來執行任務(最多20個執行緒),這個時候如果再來任務就會執行拒絕策略,
追問1:執行緒池的拒絕策略了解么?
AbortPolicy(默認):中斷直接拋例外- DiscardPolicy:默默丟棄任務,不進行任何通知
- DiscardOldestPolicy:丟棄掉在佇列中存在時間最久的任務
- CallerRunsPolicy:讓提交任務的執行緒去執行任務

課間休息,來看看我們公司樓下,坐標:北京海淀文教園,
??自從《程式人生,道阻且長》社區開啟后,投稿的圖片已經用不過來啦,贊,對了,我們會將各薪資價格區間的面試真題加入到社區中,方便大家面試前對標和準備,能正確知道自己有幾斤幾兩,
面試題3:關閉執行緒池的方式都有哪些?
shutdownNow():立即關閉執行緒池(強制),正在執行中的及佇列中的任務會被中斷,同時該方法會回傳被中斷的佇列中的任務串列;shutdown():平滑關閉執行緒池,正在執行中的及佇列中的任務能執行完成,后續進來的任務會被執行拒絕策略;isTerminated():當正在執行的任務及對列中的任務全部都執行完就會回傳,return true;
每日小結
??今天我們復習了面試中常問的執行緒池相關問題,你做到心中有數了么?對了,如果你的朋友也在準備面試,請將這個系列扔給他,如果他認真對待,肯定會感謝你的!!好了,今天就到這里,學廢了的同學,記得在評論區留言:打卡,,給同學們以激勵,
??看到這里的朋友,我得提前告訴你,
??一個不好的訊息:《Java崗大廠面試百日沖刺 - 每日3題》專欄準備改成付費專欄了,時間沒定,價格沒定,
??原因:我差錢了?是,但不全是,因為發現身邊好多朋友關注了《百日沖刺》卻從未真正跟上來過,而是感覺再給我捧場,感謝,但不需要,這些朋友們建議默默取關一下,對你我都好,不少同學反應面試中70%以上的問題專欄里出現過,說實話讓我為《百日》感到自豪,但一問你又三不知,回來來問我,我只能給你貼個路徑,
??講真,這個專欄花費了博主很多心血,白了不少根頭發,雖然很多問題總結的并不好(水平有限),但我是真希望你我能找到理想的作業,對得起自己,好了,就到這,
??對了,近期準備安排一個專門討論面試的小群,后面我在告訴你吧,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/347113.html
標籤:java
