面試題之使用無界隊列的線程池會導致內存飆升嗎?


答案:會;

分析:

創建線程池方式有如下幾種:

Executors.newFixedThreadPool(10);//LinkedBlockingQueue 無限加入隊列
Executors.newScheduledThreadPool(10);//DelayedWorkQueue 隊列如果滿了,阻塞
Executors.newSingleThreadScheduledExecutor();//DelayedWorkQueue 隊列如果滿了,阻塞
Executors.newCachedThreadPool();//SynchronousQueue 隊列如果滿了,拋異常
Executors.newSingleThreadExecutor();//LinkedBlockingQueue 無限加入隊列

jdk7提供了7個阻塞隊列,分別是:

ArrayBlockingQueue:一個由數組結構組成的有界阻塞隊列
LinkedBlockingQueue:一個由鏈表結構組成的有界阻塞隊列
PriorityBlockingQueue:一個支持優先級排序的無界阻塞隊列
DelayQueue:一個使用優先級隊列實現的無界阻塞隊列
SynchronousQueue:一個不存儲元素的阻塞隊列
LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列
LinkedBlockingDueue:一個 由鏈表結構組成的雙向阻塞隊列

 

本文以newFixedThreadPool為例,以下是jdk源碼:

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
 

參數說明:

  • corePoolSize:核心線程數
  • maximumPoolSize: 最大線程數
  • keepAliveTime:線程指定時間內獲取不到任務,則銷毀
  • unit:時間單位
  • workQueue:任務隊列

線程池工作原理圖解:

 

LinkedBlockingQueue默認的最大任務數量是Integer.MAX_VALUE,非常大,可以理解為無限大吧;但是存在這種情況,當每個線程獲取到一個任務后,執行時間比較長,導致workQueue里積壓的任務越來越多,機器的內存使用不停的飆升,最后也會導致OOM。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM