【问题标题】:join() waiting forever when exception occurs, jvm shutdown hook not working发生异常时join()永远等待,jvm关闭挂钩不起作用
【发布时间】:2016-05-16 11:43:32
【问题描述】:

我正在尝试关闭应用程序,只要有任何致命 错误/异常出现但在关闭应用程序之前我当前 线程/任务应该完成,所以我写了mainThread.join()run() 内部,它在没有异常的情况下工作正常。但每当我 doTask() 那个时候抛出异常 join() 永远等待。

public class POC 
{
    public void doTask() throws Exception
    {
        throw new Exception("Fatal Error");
        //throw new Exception("Fatal Error"); By commenting working fine.
    }

    public static void main(String[] args) 
    {
        POC ob = new POC();
        final Thread mainThread = Thread.currentThread();
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            public void run()
            {   
                try 
                {
                    System.out.println("Join() Start");
                    mainThread.join();
                    System.out.println("Join() End"); //Why this is not printing?
                } 
                catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }               
            }
        });

        try 
        {   
            System.out.println("Before doTask()");          
            ob.doTask(); //User Defined Run()
            System.out.println("After doTask()");
        }
        catch (Exception ex)                    // FATAL
        {
            System.err.println("Exception : " + ex.getLocalizedMessage());
            System.exit(-1);
        } 
    }
}

OutPut    :    0
Before Run()
Exception : Fatal Error
Join() Start

为什么System.out.println("Join() End"); 不打印?

【问题讨论】:

  • > 请告诉我,有什么解决方案可以解除死锁并强制关闭jvm。

标签: multithreading concurrency process jvm shutdown-hook


【解决方案1】:

你有一个简单的死锁。 当你抛出异常时,异常处理程序调用System.exit(-1),这是阻塞的,参见javadoc:

通过启动关闭序列来终止当前运行的 Java 虚拟机

...

虚拟机的关闭顺序包括两个阶段。在第一阶段,所有已注册的#addShutdownHook 关闭挂钩(如果有)都以某种未指定的顺序启动并允许同时运行直到它们完成

所以主线程在 System#exit 调用中等待,直到所有关闭挂钩都完成,并且您唯一的关闭挂钩阻塞并等待直到主线程完成(正在等待 System#exit ... GOTO 1)。

【讨论】:

  • > 请告诉我,有什么办法可以解除死锁并强制关闭jvm。
  • @IndrajeetKumarSharma 不要加入关闭钩子中的主线程:它会导致死锁并且没有任何意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-13
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多