Non-blocking thread that starts an external process

I created a Java GUI application that acts as a wrapper for many low-level external processes. The utility works as it is, but desperately needs one significant improvement.

I want my external process to run in a non-blocking manner, which would allow me to serve additional requests in parallel. In a nutshell, I want to be able to process data from an external process as data is generated. But it seems that my main attempt to check and check whether everything is working with an external process is blocked.

Below is a snippet of my ExternalProcess class. Please see the built-in comments on specific Java threading and blocking functionality issues.

public void Execute() { System.out.println("Starting thread ...\n"); Runner = new Thread(this, "ExternalProcessTest"); Runner.run(); System.out.println("Ending thread ...\n"); } public void run() { System.out.println("In run method ...\n"); // Debug purposes only. // Show that we are in the run loop. try { // Execute string command SomeCommand as background process ... Process = Runtime.getRuntime().exec(SomeCommand); while(IsRunning()) { // External process generates file IO. I want to process these // files inside this loop. For the purpose of this demo I have // removed all file processing to eliminate it as the cause // of blocking. THIS ROUTINE STILL BLOCKS! Thread.sleep(1000); } } catch(Exception e) { System.out.println(e); } System.out.println("Exiting run method ...\n"); // Debug purposes only. // Show that we are exiting the run loop. } // Process (instantiated from Runtime.getRuntime().execute doesn't supports // either fire-and-forget backgrounding (non-blocking) or you can wait for // the process to finish using the waitFor() method (blocking). I want to // be able to execute a non-blocking external process that I monitor via // threading allowing me to process the external process file IO as it is // created. To facilitate this goal, I have created an isRunning() method // that uses the exitValue() method. If the process is still running, a // call to exitValue() will throw an IllegalThreadStateException exception. // So I simply catch this execption to test if the background process is // finished -- at which point I can stop processing file IO from the // process. Is this the source of the blocking? If so, is there another // way to do this? public boolean IsRunning() { boolean isRunning = false; try { int exitVal = Process.exitValue(); } catch(IllegalThreadStateException e) { isRunning = true; } return isRunning; } 
+8
java multithreading nonblocking
source share
2 answers

The run () method in Thread does not actually start a new thread, try using Thread.start () instead.

+8
source share
 Runner = new Thread(this, "ExternalProcessTest"); Runner.run(); 

The run() method is misleadingly named. Since Thread implements the Runnable interface, the run() method is publicly disclosed, but it is the wrong method to call when you want to start a new thread. The run() call causes the thread code to run in the current thread.

You must call start() to instantiate a new thread:

 Runner = new Thread(this, "ExternalProcessTest"); Runner.start(); 
+6
source share

All Articles