Non-blocking thread that runs an external process

依然范特西╮ 提交于 2019-12-07 00:53:48

问题


I have created a Java GUI application which functions as a wrapper for many low level external processes. The utility works as is, but is in desperate need of one major improvement.

I want my external process run in a non-blocking manner which would permit me to service additional requests in parallel. In a nutshell I want to be able to process data from the external process as the data is being generated. But it appears my basic attempt to check and see if the external process is still running is blocking.

Below is an excerpt from my ExternalProcess class. Please see inline comments for specific Java functionality questions about threading and blocking.

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;
}

回答1:


The run() method on Thread doesn't actually start a new thread, try using Thread.start() instead.




回答2:


Runner = new Thread(this, "ExternalProcessTest");
Runner.run();

The run() method is deceptively named. Because Thread implements the Runnable interface the run() method is exposed publicly, but it is not the right method to call when you want to kick off a new thread. Calling run() causes the thread code to be run in the current thread.

You must call start() to cause a new thread to be instantiated:

Runner = new Thread(this, "ExternalProcessTest");
Runner.start();


来源:https://stackoverflow.com/questions/5942233/non-blocking-thread-that-runs-an-external-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!