溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程池詳細介紹

發(fā)布時間:2021-09-17 17:15:04 來源:億速云 閱讀:139 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“Java線程池詳細介紹”,在日常操作中,相信很多人在Java線程池詳細介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java線程池詳細介紹”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

之所以要使用線程池,是因為使用new Thread在大型項目中是有弊端的:

  1. 每次new Thread新建對象,性能差

  2. 線程缺乏統(tǒng)一管理,可能無限制的新建線程,相互競爭,有可能會造成過多占用系統(tǒng)資源而導致OOM

  3. 缺少更多功能,如定期執(zhí)行等

而線程池的好處:

  1. 重用存在的線程,減少對象創(chuàng)建、消亡的開銷,性能佳

  2. 可有效控制最大并發(fā)線程數(shù),提高系統(tǒng)資源利用率,同時可以避免過多資源競爭,避免阻塞

  3. 提供定時執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能

狀態(tài)池的狀態(tài)轉(zhuǎn)換

Java線程池詳細介紹

線程池的類繼承關(guān)系

  1. Executor是一個頂層接口,在它里面只聲明了一個方法execute(Runnable),返回值為void,參數(shù)為Runnable類型,從字面意思可以理解,就是用來執(zhí)行傳進去的任務的

  2. ExecutorService接口繼承了Executor接口,并聲明了一些方法:submit、invokeAll、invokeAny以及shutDown等

  3. 抽象類AbstractExecutorService實現(xiàn)了ExecutorService接口,基本實現(xiàn)了ExecutorService中聲明的所有方法

  4. ThreadPoolExecutor繼承了類AbstractExecutorService。

ThreadPoolExecutor的方法說明

  1. execute()實際上是Executor中聲明的方法,在ThreadPoolExecutor進行了具體的實現(xiàn),這個方法是ThreadPoolExecutor的核心方法,通過這個方法可以向線程池提交一個任務,交由線程池去執(zhí)行

  2. submit()方法是在ExecutorService中聲明的方法,在AbstractExecutorService就已經(jīng)有了具體的實現(xiàn),在ThreadPoolExecutor中并沒有對其進行重寫,這個方法也是用來向線程池提交任務的,但是它和execute()方法不同,它能夠返回任務執(zhí)行的結(jié)果,去看submit()方法的實現(xiàn),會發(fā)現(xiàn)它實際上還是調(diào)用的execute()方法,只不過它利用了Future來獲取任務執(zhí)行結(jié)果

  3. shutdown()優(yōu)雅關(guān)閉線程池

  4. shutdownNow()強制關(guān)閉線程池

還有很多其他的方法:比如:getQueue() 、getPoolSize() 、getActiveCount()、getCompletedTaskCount()等獲取與線程池相關(guān)屬性的方法,可以用于線程池監(jiān)控,有興趣的朋友可以自行查閱API。

更多ThreadPoolExecutor配置的詳細說明,點擊查看:還在用Executors創(chuàng)建線程池?小心內(nèi)存溢出

ScheduledExecutorService使用說明

@Slf4jpublic class ThreadPoolExample {
   public static void main(String[] args) {
       ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
       // 延時任務//        executorService.schedule(()->//                log.warn("schedule run"), 3, TimeUnit.SECONDS);
       // 固定速率任務        executorService.scheduleAtFixedRate(()                -> log.warn("schedule run"), 1, 3, TimeUnit.SECONDS);//        executorService.shutdown();
       // Timer也能執(zhí)行定時任務,不過還是推薦用ScheduledExecutorService//        Timer timer = new Timer();//        timer.schedule(new TimerTask() {//            @Override//            public void run() {//                log.warn("timer run");//            }//        }, new Date(), 5 * 1000);    }}

特別提示:通過ScheduledExecutorService執(zhí)行的周期任務,如果任務執(zhí)行過程中拋出了異常,那么ScheduledExecutorService就會停止執(zhí)行任務,而且也不會再周期地執(zhí)行該任務了。所以如果想保持任務周期執(zhí)行,需要catch一切可能的異常。

線程池核心線程數(shù)配置推薦

CPU密集型任務:盡量壓榨CPU,參考值設(shè)置為NCPU+1
IO密集型任務:參考值可以設(shè)置為2*NCPU

相關(guān)的線程池

Spring的異步線程池

TaskExecutor是Spring異步線程池的接口,繼承Java.util.concurrent.Executor接口

Spring已經(jīng)實現(xiàn)的異步線程池(TaskExecutor的實現(xiàn)類):

  1. SimpleAsyncTaskExecutor:不是真的線程池,這個類不重用線程,每次調(diào)用都會創(chuàng)建一個新的線程。

  2. SyncTaskExecutor:這個類沒有實現(xiàn)異步調(diào)用,只是一個同步操作。只適用于不需要多線程的地方

  3. ConcurrentTaskExecutor:Executor的適配類,不推薦使用。如果ThreadPoolTaskExecutor不滿足要求時,才用考慮使用這個類

  4. SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的類。線程池同時被quartz和非quartz使用,才需要使用此類

  5. ThreadPoolTaskExecutor :最常使用,推薦。 其實質(zhì)是對java.util.concurrent.ThreadPoolExecutor的包裝

Spring的異步線程池的使用

  1. @Async將方法標注為異步方法,Spring掃描到后,執(zhí)行該方法時,會另起新線程去執(zhí)行,非常簡單

  2. 為了讓@Async注解能夠生效,還需要在Spring Boot的主程序中配置@EnableAsync

@Async所修飾的函數(shù)不要定義為static類型,這樣異步調(diào)用不會生效

到此,關(guān)于“Java線程池詳細介紹”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI