CompletableFuture.runAsync(() -> doSomething());
在doSomething()中調(diào)用Thread.currentThread().getContextClassLoader()時(shí)返回null端蛆。
使用Stream.parallel()也會(huì)出現(xiàn)此現(xiàn)象铺坞。
原因:
(https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8184335) JDK9后修復(fù)
In Java SE 9, threads that are part of the fork/join common pool will always return the system class loader as their thread context class loader. In previous releases, the thread context class loader may have been inherited from whatever thread causes the creation of the fork/join common pool thread, e.g. by submitting a task. An application cannot reliably depend on when, or how, threads are created by the fork/join common pool, and as such cannot reliably depend on a custom defined class loader to be set as the thread context class loader.
在Java9中,fork/join common pool會(huì)始終返回系統(tǒng)類加載器作為上下文類加載器。而之前的版本上下文類加載器可能從觸發(fā)fork/join common pool創(chuàng)建的線程繼承而來(lái)。
好吧 看來(lái)common pool返回null才是期望的。(這里的common pool 指的就是ForkJoinCommonPool)
此外躬厌,使用ForkJoinPool還會(huì)導(dǎo)致內(nèi)存泄漏 :TestCase
Tomcat 8.5.11 版本后修復(fù):擴(kuò)展JreMemoryLeakPreventionListener 防止內(nèi)存泄漏
解決方案
- 使用自定義線程池
CompletableFuture.runAsync(() -> doSomething(), myExecutor);
- 如果非要使用ForkJoinPool,那么就自己創(chuàng)建一個(gè)
ForkJoinPool forkJoinPool = new ForkJoinPool(NUM);
forkJoinPool.execute(() -> doSomeThing());