您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java線程池詳細介紹”,在日常操作中,相信很多人在Java線程池詳細介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java線程池詳細介紹”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
之所以要使用線程池,是因為使用new Thread在大型項目中是有弊端的:
每次new Thread新建對象,性能差
線程缺乏統一管理,可能無限制的新建線程,相互競爭,有可能會造成過多占用系統資源而導致OOM
缺少更多功能,如定期執行等
而線程池的好處:
重用存在的線程,減少對象創建、消亡的開銷,性能佳
可有效控制最大并發線程數,提高系統資源利用率,同時可以避免過多資源競爭,避免阻塞
提供定時執行、定期執行、單線程、并發數控制等功能
Executor是一個頂層接口,在它里面只聲明了一個方法execute(Runnable),返回值為void,參數為Runnable類型,從字面意思可以理解,就是用來執行傳進去的任務的
ExecutorService接口繼承了Executor接口,并聲明了一些方法:submit、invokeAll、invokeAny以及shutDown等
抽象類AbstractExecutorService實現了ExecutorService接口,基本實現了ExecutorService中聲明的所有方法
ThreadPoolExecutor繼承了類AbstractExecutorService。
execute()實際上是Executor中聲明的方法,在ThreadPoolExecutor進行了具體的實現,這個方法是ThreadPoolExecutor的核心方法,通過這個方法可以向線程池提交一個任務,交由線程池去執行
submit()方法是在ExecutorService中聲明的方法,在AbstractExecutorService就已經有了具體的實現,在ThreadPoolExecutor中并沒有對其進行重寫,這個方法也是用來向線程池提交任務的,但是它和execute()方法不同,它能夠返回任務執行的結果,去看submit()方法的實現,會發現它實際上還是調用的execute()方法,只不過它利用了Future來獲取任務執行結果
shutdown()優雅關閉線程池
shutdownNow()強制關閉線程池
還有很多其他的方法:比如:getQueue() 、getPoolSize() 、getActiveCount()、getCompletedTaskCount()等獲取與線程池相關屬性的方法,可以用于線程池監控,有興趣的朋友可以自行查閱API。
更多ThreadPoolExecutor配置的詳細說明,點擊查看:還在用Executors創建線程池?小心內存溢出
@Slf4j
public 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也能執行定時任務,不過還是推薦用ScheduledExecutorService
// Timer timer = new Timer();
// timer.schedule(new TimerTask() {
// @Override
// public void run() {
// log.warn("timer run");
// }
// }, new Date(), 5 * 1000);
}
}
特別提示:通過ScheduledExecutorService執行的周期任務,如果任務執行過程中拋出了異常,那么ScheduledExecutorService就會停止執行任務,而且也不會再周期地執行該任務了。所以如果想保持任務周期執行,需要catch一切可能的異常。
CPU密集型任務:盡量壓榨CPU,參考值設置為NCPU+1
IO密集型任務:參考值可以設置為2*NCPU
TaskExecutor是Spring異步線程池的接口,繼承Java.util.concurrent.Executor接口
Spring已經實現的異步線程池(TaskExecutor的實現類):
SimpleAsyncTaskExecutor:不是真的線程池,這個類不重用線程,每次調用都會創建一個新的線程。
SyncTaskExecutor:這個類沒有實現異步調用,只是一個同步操作。只適用于不需要多線程的地方
ConcurrentTaskExecutor:Executor的適配類,不推薦使用。如果ThreadPoolTaskExecutor不滿足要求時,才用考慮使用這個類
SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的類。線程池同時被quartz和非quartz使用,才需要使用此類
ThreadPoolTaskExecutor :最常使用,推薦。 其實質是對java.util.concurrent.ThreadPoolExecutor的包裝
@Async將方法標注為異步方法,Spring掃描到后,執行該方法時,會另起新線程去執行,非常簡單
為了讓@Async注解能夠生效,還需要在Spring Boot的主程序中配置@EnableAsync
@Async所修飾的函數不要定義為static類型,這樣異步調用不會生效
到此,關于“Java線程池詳細介紹”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。