运行外部进程的非阻塞线程
问题描述:
我创建了一个Java GUI应用程序,它充当许多低级外部进程的包装。公用事业按原样运作,但迫切需要一项重大改进。运行外部进程的非阻塞线程
我希望我的外部进程以非阻塞的方式运行,这将允许我并行地处理额外的请求。简而言之,我希望能够在生成数据时处理来自外部进程的数据。但它似乎是我的基本尝试,检查并看看外部进程是否仍在运行正在阻塞。
下面是我的ExternalProcess类的摘录。有关线程和阻塞的特定Java功能问题,请参阅内联注释。
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;
}
答
Thread上的run()方法实际上并未启动新线程,请尝试使用Thread.start()代替。
答
Runner = new Thread(this, "ExternalProcessTest");
Runner.run();
run()
方法被误导地命名。因为Thread
实现Runnable
接口run()
方法是公开的,但它是而不是当您想要启动新线程时调用正确的方法。调用run()
会导致线程代码在当前的线程中运行。
必须调用start()
导致被实例化一个新的线程:
Runner = new Thread(this, "ExternalProcessTest");
Runner.start();
+0
谢谢约翰。那样做了。我感谢你抽出时间。 – Rodney 2011-05-09 21:20:15
哇。那非常骨头。但你是对的。那样做了。非常感谢Mike! – Rodney 2011-05-09 21:17:19
我不止一次为此而堕落。 :-) – 2011-05-10 05:23:38