我有一些如下所示的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中的所有代码的情况下,我无法提供一个可重复性最低的示例,这是不可行的,但我已经验证了以下内容:

  • 在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]:

这个池是静态构造的;它的运行状态不受try Shutdown()或Shudown Now()的影响.但是,这个池和任何正在进行的处理都会在程序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");
        }

这只是我的猜测.

Java相关问答推荐

我可以从Java模块中排除maven资源文件夹吗?

我想了解Java中的模块化.编译我的应用程序时,我有一个ResolutionException

嵌入式ActiveMQ Artemis Web控制台加载错误

Java中的死锁及其重入锁和锁

为什么S的文档中说常量方法句柄不能在类的常量池中表示?

与不同顺序的组进行匹配,不重复组但分开

Log4j与jdk21兼容吗?

Java泛型类方法的静态返回类型是否被类型擦除?

将JSON字符串转换为Java类

在处理2个映射表时,没有更多的数据可从套接字读取

JNI:将代码打包成自包含的二进制文件

基于配置switch 的@Controller的条件摄取

如何在Jooq中获取临时表列引用?

在Java中将.GRF转换为图像文件

H2数据库仅支持%1个结果集?

我无法在我的Spring Boot应用程序中导入CSV依赖项

如何在单元测试中获得我的装饰Mapstruct映射器的实例?

Java 21保护模式的穷尽性

如何在java中从以百分比表示的经过时间和结束日期中找到开始日期

一条Java记录可以保存多少个字段?