newFixedThreadPool @Slf4j public class TheadPoolDemo { private static ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPoo ...
newFixedThreadPool
@Slf4j public class TheadPoolDemo { private static ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(10); public static void newFixedThreadPool() throws Exception { for (int i = 0; i < 2000000000; i++) { threadPool.execute(() -> { String payload = IntStream.rangeClosed(1, 90000000).mapToObj(__ -> "a").collect(Collectors.joining("")) + UUID.randomUUID().toString(); try { TimeUnit.HOURS.sleep(1); } catch (InterruptedException e) { } log.info(payload); }); } threadPool.shutdown(); threadPool.awaitTermination(1, TimeUnit.HOURS); } }
運行一段時間後oom
原因分析
無界隊列
果任務較多並且執行較慢的話,隊列可能會快速積壓,撐爆記憶體導致 OOM
newCachedThreadPoo
private static ThreadPoolExecutor threadPoolCached = (ThreadPoolExecutor) Executors.newCachedThreadPool(); public static void newCachedThreadPool() throws Exception { for (int i = 0; i < 2000000000; i++) { threadPoolCached.execute(() -> { String payload = IntStream.rangeClosed(1, 90000000).mapToObj(__ -> "a").collect(Collectors.joining("")) + UUID.randomUUID().toString(); try { TimeUnit.HOURS.sleep(1); } catch (InterruptedException e) { } log.info(payload); }); } threadPool.shutdown(); threadPool.awaitTermination(1, TimeUnit.HOURS); }
運行一段時間後oom
原因分析
這種線程池的最大線程數是 Integer.MAX_VALUE,可以認為是沒有上限的,而其工作隊列 SynchronousQueue 是一個沒有存儲空間的阻塞隊列。
這意味著,只要有請求到來,就必須找到一條工作線程來處理,如果當前沒有空閑的線程就再創建一條新的。
大量的任務進來後會創建大量的線程。線程是需要分配一定的記憶體空間作為線程棧的,比如 1MB,因此無限制創建線程必然會導致 OOM。
線程池預設策略