我有一些像这样的Java代码:
IntStream.range(0, N)
.parallel()
.forEach(
i -> {
// do some work
});
运行此代码时会看到以下警告:
[WARNING] thread Thread[#73,ForkJoinPool.commonPool-worker-8,5,] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[#73,ForkJoinPool.commonPool-worker-8,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#74,ForkJoinPool.commonPool-worker-9,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#75,ForkJoinPool.commonPool-worker-10,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#76,ForkJoinPool.commonPool-worker-11,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#77,ForkJoinPool.commonPool-worker-12,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#78,ForkJoinPool.commonPool-worker-13,5,] will linger despite being asked to die via interruption
[WARNING] thread Thread[#79,ForkJoinPool.commonPool-worker-14,5,] will linger despite being asked to die via interruption
[WARNING] NOTE: 7 thread(s) did not finish despite being asked to via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
如果不复制粘贴 lambda 中的所有代码,我就无法提供最低限度可重现的示例,这是不可行的,但我已经验证了以下内容:
mvn spring-boot:run
运行应用程序,警告就会消失,但如果通过 mvn exec:java
执行应用程序,警告就会出现。据我了解,前者会产生一个新的 JVM,而后者则不会。如果有任何帮助或提示来解决此问题,我将不胜感激。
据我所知,这是另一个 Maven 问题,因为如果直接通过
java
执行代码,则不会出现错误或警告。
我认为解释是,当使用
mvn exec:java
执行程序时,程序不会在主线程上运行。 Maven 在工作线程上运行程序 [1]:
Thread bootstrapThread = new Thread(
threadGroup,
() -> {
int sepIndex = mainClass.indexOf('/');
final String bootClassName;
...
mainHandle.invoke(arguments); // runs our main class
...
bootstrapThread.start();
joinNonDaemonThreads(threadGroup);
...
并且
ForkJoin
公共池中的线程在主线程退出之前不会关闭[2]:
这个池是静态构建的;它的运行状态不受尝试 shutdown() 或 shutdownNow() 的影响。然而,这个池和任何正在进行的处理都会在程序 System.exit(int) 时自动终止。
因此打断它们不会关闭它们[3]。
// executed as a result of call to joinNonDaemonThreads
if (thread.isAlive()) // generally abnormal
{
getLog().warn("thread " + thread + " was interrupted but is still alive after waiting at least "
+ timeoutMsecs + "msecs");
}
只是我的猜测。