我从哪里开始研究不会结束的Java进程?

时间:2010-07-13 10:57:38

标签: java eclipse multithreading

我有一个不会结束的Java应用程序。 main方法完成,但线程保持活动状态,应用程序不会结束。问题是,似乎没有任何监视器锁定/等待,所以我不明白为什么它没有结束。根据Eclipse,我留下了两个非守护进程线程。一个标记为[DestroyJavaVM](看起来很有希望!),另一个似乎在Unsafe.park(boolean, long)中被阻止。我应该如何/在哪里开始调查这个?

第二个帖子的删节栈跟踪是:

   Unsafe.park(boolean, long)
at LockSupport.park(Object)
at AbstractQueuedSynchronizer$ConditionObject.await()
at LinkedBlockingQueue<E>.take()
at ThreadPoolExecutor.getTask()
at ThreadPoolExecutor$Worker.run()
at Thread.run() 

5 个答案:

答案 0 :(得分:1)

您需要执行以下两项操作之一来终止ExecutorService主题:

  1. 指定创建守护程序线程的ThreadFactory(来自ThreadFactoryBuilderGuava类将使这更容易。)
  2. 作为应用程序关闭的一部分,在shutdown()上致电ExecutorService(例如,在main方法结束时。)

答案 1 :(得分:0)

线程转储和调试器将是我的猜测。

答案 2 :(得分:0)

不确定应用程序的大小,但我会检查您创建的所有线程,并确保在应用程序执行完毕后干净地退出其运行方法。在某个地方,在一个线程中,你可能有以下代码:

public void run() {
    while(true) { //"true" or some condition that never gets a chance to be false
        //do thread related work
    }
}

答案 3 :(得分:0)

Unsafe.park,尽管名字听起来很恐怖,但通常被各种阻塞调用使用(特别是那些新的(ish)java.util.concurrent包中)。

如果你在堆栈的下方看几帧,你会看到类似java.util.concurrent.LinkedBlockingQueue.take(即一些JDK库类)的东西,然后是类似com.example.myapp.MyClass.getNextJob的东西(即你正在使用该库的类)类)。

如果我不得不冒险猜测,我会说你正在做一些永远阻止的电话 - 所以当没有什么可以再回来的时候,这个线程只是坐在那里等待“下一个”项目。您可以通过设置某种“已完成”标志来解决此问题,然后中断等待线程或使阻塞调用超时,让它检查标志。根据您的代码中的任何一个或替代方案都是可行的,但希望这足以让您入门。

编辑:看到堆栈跟踪,finnw is right,您需要关闭执行服务。

答案 4 :(得分:0)

您的任务被阻止等待队列中的数据。 Take没有与之相关的超时。

在创建任务线程时保持对其的引用。在关闭时,调用线程上的中断方法。您可能还需要修改调用take的工作处理循环,以便在捕获InterruptedException时退出。