當一個java新手從不斷地Curd階段跳出來之後,就會學習java的並發,並行等高階用法,自然就會用到線程、線程池,線程池的好處這裡就不做詳細解釋,你應該會學習到Executors創建線程池的四個方法, 分別是:
newFixedThreadPool(int Threads):創建固定數目的線程池。newSingleThreadPoolExecutor():創建一個單線程的線程池。newCacheThreadPool():創建一個可緩存的線程池,調用execute將重用以前構成的線程。newScheduledThreadPool(int corePoolSize):創建一個支持定時及周期性的任務執行的線程池。常用的方法是newFixedThreadPool和newCacheThreadPool。
但是,阿里巴巴的《Java開發手冊》關於線程池的用法中明確地指出:不允許使用Executors來創建線程池。
原因分析
從上圖分析都可以知道都是因為用Executors默認方法創建線程池,會允許創建最大長度為Integer.MAX_VALUE或者是大量的請求,從而導致OOM, 下面從new SingleExecutor源碼分析:
可以發現,在創建LinkedBlockingQueue時,並未指定容量。此時,LinkedBlockingQueue就是一個無邊界隊列,對於一個無邊界隊列來說,是可以不斷的向隊列中加入任務的,就有可能因為任務過多而導致內存溢出的問題。
正確的方式如下:
直接調用ThreadPoolExecutor的構造函數自己創建線程池,給BlockQueue指定容量就可以了。
阿里巴巴推薦線程池創建方式
方式1:commons-lang3
方式2:com.google.guava
方式3:ThreadPoolExecutor或者spring配置線程池方式
調用execute(Runnable task)方法即可
總結
java新手應該避免一開始就使用錯誤的方式,上面就是正確創建線程池的方式推薦,希望對你有所幫助。