join()在发生异常时永远等待,jvm shutdown hook无法正常工作

时间:2016-05-16 11:43:33

标签: multithreading concurrency process jvm shutdown-hook

我试图关闭应用程序,无论何时致命 错误/异常出现但在关闭应用程序之前我的当前 线程/任务应该完成,所以我写了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");没有打印?

1 个答案:

答案 0 :(得分:1)

你有一个简单的死锁。 抛出异常时,异常处理程序调用{​​{1}},即阻塞,请参阅javadoc:

  

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

     

...

     

虚拟机的关闭序列包含两个阶段。在第一阶段,所有已注册的System.exit(-1)关闭挂钩(如果有)以某种未指定的顺序启动,并允许同时运行直到完成

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