Я создал приложение с графическим интерфейсом Java, которое функционирует как оболочка для многих низкоуровневых внешних процессов. Утилита работает как есть, но остро нуждается в одном серьезном улучшении.
Я хочу, чтобы мой внешний процесс выполнялся неблокирующим образом, что позволило бы мне обслуживать дополнительные запросы параллельно. Короче говоря, я хочу иметь возможность обрабатывать данные из внешнего процесса во время генерации данных. Но, похоже, моя основная попытка проверить, не блокируется ли внешний процесс, все еще работает.
Ниже приведен отрывок из моего класса 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;
}