【问题标题】:The web application [VehicleRouting] appears to have started a thread named [drools-worker-4] but has failed to stop itWeb 应用程序 [VehicleRouting] 似乎已经启动了一个名为 [drools-worker-4] 的线程,但未能停止它
【发布时间】:2017-11-10 21:39:12
【问题描述】:

我使用 optaplanner 构建了一个车辆路线网络应用程序。当我尝试将我的 Web 应用程序部署到 tomcat 8 服务器并尝试从我的 Web 浏览器运行它时,它会在我的 tomcat 日志文件中产生警告。日志说我的 Web 应用程序启动了一个线程但未能停止它,并且可能会造成内存泄漏。 我编写了一个销毁方法,其中我的 ExecutorService 对象将调用关闭方法以确保它启动的每个线程都已终止。这是我的代码:

public class OptimizerService implements IOptimizerService {
    private ExecutorService executor;

    @Override
    public synchronized Boolean startSolving() throws Throwable {
        executor = Executors.newFixedThreadPool(2);
        ...
    }

    ...
    // other methods 
    ...

    @PreDestroy
    public synchronized void destroy() {
        executor.shutdown();
    }
}

但是为什么我仍然在 tomcat 日志中收到这些警告? 这是tomcat日志:

09-Jun-2017 08:25:56.377 WARNING [http-nio-18081-exec-295] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [VehicleRouting] appears to have started a thread named [drools-worker-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.misc.Unsafe.park(Native Method)
 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 java.lang.Thread.run(Thread.java:745)

任何评论将不胜感激。谢谢和问候。

【问题讨论】:

    标签: java multithreading tomcat servlets optaplanner


    【解决方案1】:

    executor.shutdownNow(); 会中断线程,但executor.shutdown(); 不会。后者只是等到任务完成,如果你有一个运行 2 小时的求解器,祝你好运......

    如果Solver 检测到它的线程被中断,它就会终止(与普通的Termination 几乎相同),然后调用KieSession.dispose()。我认为dispose() 负责处理任何流口水产生的线程。

    至少理论上是这样的:)

    【讨论】:

    • 也可能只是由this jira fixed for 7引起的。
    • 那么你的意思是我应该使用 executor.shutdownNow() 而不是 executor.shutdown() 吗?如果我使用 executor.shutdownNow(),它会让求解器自动检测线程中断,并终止并处理所有 drools 产生的线程,对吗?
    • 我已经使用 executor.shutdownNow();但 tomcat 服务器仍然在日志文件中产生相同的错误。这是一个危险的问题吗?..任何其他想法如何解决这个问题?..
    猜你喜欢
    • 2017-06-09
    • 2017-12-26
    • 2011-08-19
    • 2014-10-31
    • 1970-01-01
    • 2017-12-07
    • 2014-09-27
    • 2014-09-11
    • 2017-08-12
    相关资源
    最近更新 更多