开发者

How do I stop Ant from hanging after executing a java program that attempted to interrupt a thread (and failed) and continued?

I have Ant build and execute a java program. This program tries to do something that sometimes hangs, so we execute it in a thread.

actionThread.start();
try {
    actionThread.join(10000);
} catch (InterruptedException e) {
    System.out.println("InterruptedException: "+e.getMessage());
} 
if (actionThread.isAlive()) {
    actionThread.interrupt();
    System.out.println("Thread timed out and never died");
}

The ant call looks like this:

<java fork="true" failonerror="yes" classname="myPackage.myPathName" classpath="build">  
    <arg line=""/>
    <classpath>
        <pathelement location="bin" />
        <fileset dir="lib">
            <include name="**/*.jar"/>
        </fileset>
    </classpath>
</java>

And when this runs I see the "Thread timed out and never died" statement, and I also see the main program finish execution, but then Ant just hangs. Presumably it is waiting for the child threads to finish, but they never will.

How can I have Ant be done once it is done execut开发者_StackOverflow社区ing main() and just kill or ignore dead threads?


You can use public final void setDaemon(boolean on) method of the Thread class i.e actionThread.setDaemon(true). That way you will ensure that JVM exits once the main Thread is finished.

Java Doc says:

Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.

This method must be called before the thread is started.

UPDATE


System.exit() Vs Daemon thread

For a bigger piece of code you cannot always be sure that all the active threads are the daemon threads. If a new thread is created by the daemon thread and if its setDaemon(true) is not set then it will inherit it from the parent. Although there can be scenarios where the newly created thread is set as a non-daemon (and then we will face your current problem).

I personally think if you are done then you can call System.exit(0);

As per Java doc for System.exit():

Terminates the currently running Java virtual machine by initiating its shutdown sequence. This method never returns normally...In the first phase all registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish. In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.

There are other SO post where they have discussed this:

When should we call System.exit in Java

System.exit() can be used to run shutdown hooks before the program quits. This is a convenient way to handle shutdown in bigger programs, where all parts of the program can't (and shouldn't) be aware of each other.

From which thread should System.exit() be called in a Swing-app?

The GC would take a while before things are rounded off and the app exits. There is nothing wrong with calling System.exit, once you dealt with closing what you ought to.

As a third solution (1st is System.exit() , 2nd setDaemon()) you can also check for interrupted threads before doing any processing or decide 'what to do' in the handling of InterruptedException.

Hope this will help.


I agree with Favonius that using a daemon thread is the way to go. However, you may also want to make sure that your background thread is actually handling interrupt() correctly. There's a common misconception that calling Thread.interrupt() will automatically terminate a thread, which is not true. Here's a quote from the Java Concurrency Tutorial:

An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.

If the background thread is stuck in a blocking operation like Thread.sleep(), Object.wait(), or certain I/O operations, then calling interrupt() will usually cause InterruptedException to be thrown inside that thread. It is the thread's responsibility (i.e. your code) to catch that exception and decide what to do -- for example, returning immediately (and ending the thread).

In other cases, you may need to manually check the Thread.interrupted() at key points in your code to see if interrupt() was called.

Hope this helps. You can read the full article for details.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜