views:

333

answers:

6

I have a Java application that creates a new thread to do some work. I can launch the new thread with no problems.

When the "main" program terminates, I want the thread I created to keep running - which it does...

But the problem is, when I run the main application from Eclipse or from Ant under Windows, control doesn't return unless the background process is killed.

If I fork the main java process in ant, I want control to return to ant once the main thread is done with its work... But as it is, ant continues to wait until both the main process and the created thread are both terminated.

How do I launch the thread in the background such that control will return to ant when the "main" application is finished? (By the way, when I run the same application under Linux, I am able to do this with no problems).

+1  A: 

You probably want to create a daemon thread: thread.setDaemon (true).

Roman
It more sounds like that he just want to keep the thread running also when the main program is terminated.
BalusC
This doesn't work for me. The environment still hangs upon termination of the main program.
Bob
+1  A: 

Your best bet is to launch a completely independent program for that, which is independent from the launching program. You can do that with Runtime#exec(), ProcessBuilder or Desktop#open().

BalusC
I see. I think that a separate process will work. Any ideas about the reason for the hang in the first place? Is it because the threads are using the same JVM?
Bob
Indeed, it's using the same process. I must however admit that I am not entirely sure if any of the proposed solutions would actually launch a *separate* process. `Desktop#open()` would certainly do. But the other two.. Can't tell that from experience :)
BalusC
A: 

It sounds like you need the "main" thread and the "background" thread to be separate processes. Fork the first process, which runs the "main" thread. That process, in turn, forks a second process that runs the "background" thread. On Windows, you may have to start the background process (via Java's Runtime.exec() API) using start /b

I don't understand how this is working under Linux. A Process created by Runtime.exec() is either running or its not. When a Java program waits for a Process to complete, it doesn't care if there is one thread or many running in the sub-process. If you can describe more clearly how you have it working under Linux it might help.

erickson
A: 

Control will not return from the JVM until everything is finished. This means all threads have to return and all windows have to be destroy()ed--and main has to exit.

Or you call System.exit().

If it did work on Linux, I'm pretty sure you'll find that your background thread also terminated--otherwise this is Very Bad.

Bill K
+1  A: 

If I understand the question correctly, it seems that the program is behaving correctly... the main thread finishes and exits, while the "background" thread keeps running. The JVM will not exit until all non-daemon threads terminate. If you want the JVM process to terminate when the main thread terminates, you need to do as Roman indicates and call Thread.setDaemon(boolean).

However, if the problem is that the main thread terminates properly, but background never terminates, even though it has finished the task you've given it, then perhaps background is deadlocked.

The best first-step IMO is to run VisualVM on the process to dump stack and use its thread debugging tools to find out what background is doing and why it's hung. (You can also cause the JVM to dump stack by sending it kill -QUIT <pid> if on *nix... there's something similar on windows with the Break key, but I can't remember the specifics.) The stack dumps in Java 6 are quite sophisticated, and will indicate possible deadlocks with the objects each thread is locked on.

VisualVM is just fun to use, so try it out if you've never used it.

Simeon Fitch
A: 

I figured things out. As it turns out, in Windows, processes launched from the same command window will wait until child processes are finished.

You can test this in eclipse: Make a program and exec an application (eg. Notepad.exe). You'll find that the java program terminates, but the red button is still active. Control doesn't return to eclipse until you close out your application (eg. notepad.exe). This is apparently because your java program and the execed program are using the same command window. The same thing happens in ANT.

In linux, processes don't inherit the command window like in windows, so control returns to eclipse when your process finishes.

In both cases, the spawned process remains alive until it is terminated.

Bob