16

The goal is to be able to invoke execution of a separate thread from within the main class.

Some context: I have a program that must run a process. The process (a cmd one) should run only when the main program is done executing and is unloaded from memory.

What code should I include in the main class?

mtotowamkwe
  • 2,407
  • 2
  • 12
  • 19
helpmepls
  • 163
  • 1
  • 1
  • 4
  • I know this is late, but did you take a look at [`ProcessBuilder`](http://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html) as a different option? – mkobit Sep 03 '15 at 00:18

5 Answers5

33

If you mean: how can I start a Java thread that will not end when my JVM (java program) does?.

The answer is: you can't do that.

Because in Java, if the JVM exits, all threads are done. This is an example:

class MyRunnable implements Runnable { 
   public void run() { 
       while ( true ) { 
           doThisVeryImportantThing(); 
       } 
   } 
} 

The above program can be started from your main thread by, for example, this code:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable);
myThread.start(); 

This example program will never stop, unless something in doThisVeryImportantThing will terminate that thread. You could run it as a daemon, as in this example:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable);
myThread.setDaemon(true); // important, otherwise JVM does not exit at end of main()
myThread.start(); 

This will make sure, if the main() thread ends, it will also terminate myThread.

You can however start a different JVM from java, for that you might want to check out this question: Launch JVM process from a Java application use Runtime.exec?

Community
  • 1
  • 1
Kdeveloper
  • 13,679
  • 11
  • 41
  • 49
  • 1
    After myThread.start() is called, what happens to myRunnable? Can one still interact with it as usual (e.g. call methods besides run())? – aednichols Mar 07 '13 at 01:23
5

Create a separate thread that executes your external program:

class MyRunner implements Runnable{
  public void run(){
     Runtime.exec("your cmd")
  }
}

then start the thread in your main():

MyRunner myRunner = new MyRunner(); 
Thread myThread = new Thread(myRunner);
myThread.start();

This way your main program will continue running, while your background thread will start an external process and exit when this program exits.

Peter Knego
  • 79,991
  • 11
  • 123
  • 154
0

Sounds like you want a script which calls the first program and then when the first finishes, it calls the second program.

Something like

program1
program2

EDIT: To run the two tasks in parallel you can do

program1 &
program2

in a bash/unit shell.

or in dos shell

start program1
program2
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Actually not. I have main class which makes me 1 process and that process SHOULD not block main program (that what I thought) and must do his work separately from main class. – helpmepls Oct 23 '10 at 18:14
  • You have stated that you require "That process (a cmd one) runs only when main program finished and unloaded from memory". Using Runtime.exec() starts the second process before the first one finished and before it is unloaded. – Peter Lawrey Oct 24 '10 at 10:12
  • You last comment suggests you want the two processes to run at the same time. – Peter Lawrey Oct 24 '10 at 10:16
0

I'm not altogether sure you can make a 'detached' thread in Java using the normal means of implementing Thread and kicking it off with run().

You might need to fork a thread using Runtime.exec(), running java as wholly separate process, not as a thread.

Tony Ennis
  • 12,000
  • 7
  • 52
  • 73
  • I use Runtime.exec() to run process, but that process won't start working (but he is UP and kind of suspend or something) until my main program not quited. – helpmepls Oct 23 '10 at 18:35
  • If you're running a *nix, I believe you can detach the process by putting an ampersand behind the command: `top &` – Tony Ennis Oct 23 '10 at 18:39
  • Perhaps you can use cygwin? Are you saying you can make a new process in Windows but it is suspended for as long as you main program is running? If so, it almost sounds like they are competing for a resource. Can you fork a different process, such as something that displays the contents of a large file, so make sure they aren't fighting over a resource? – Tony Ennis Oct 23 '10 at 18:53
  • There are many related threads on SO: http://stackoverflow.com/search?q=windows+runtime+java – Tony Ennis Oct 23 '10 at 18:55
  • I'll try your hint about an ampersand in ubuntu later. Link you gave provide not so much help about my problem, sorry xD – helpmepls Oct 23 '10 at 19:18
0

To spawn a process that survives after the JVM terminates you'll need to use Runtime.exec(). Since you want it to run after your main process ends, there are really two ways you can do it:

1) If you only want to process to run during a clean shutdown then you can do this:

public static void main(String[] args) {
    doThisProgramsStuff();
    spawnSecondProcess();
}

2) Or, if you want the process to run even with an unclean shutdown (or if it's a GUI application) then you can add a shutdown hook:

public static void main(String[] args) {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            spawnSecondProcess();
        }
    });
    doThisProgramsStuff();
}

There is, however, a problem with all this. Once the JVM terminates the child process will have standard input/output attached to nothing, so it might fill it's output buffers and block. You'll need to do something to make sure this doesn't happen by either making sure the process does not produce output to those streams or by doing the Windows equivalent of redirecting to /dev/null.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86