2011-05-09 3 views
8

많은 저수준 외부 프로세스에 대한 래퍼로 작동하는 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; 
} 

답변

8

Thread의 run() 메서드는 실제로 새 스레드를 시작하지 않으므로 Thread.start()를 대신 사용해보십시오.

+1

와우. 그것은 꽤 뼈가 향했다. 그러나 당신은 정확합니다. 그랬어. 마이크 대단히 감사합니다! – Rodney

+1

나는 한 번 이상 그 자신을 위해 넘어졌다. :-) –

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

run() 방법은 믿을 수없는 이름입니다. ThreadRunnable 인터페이스를 구현하므로 run() 메서드는 공개적으로 노출되지만 이 아니며 새 스레드를 시작하려는 경우 올바른 메서드를 호출해야합니다. run()을 호출하면 현재 스레드에서 스레드 코드가 실행됩니다.

새 스레드가 인스턴스화되도록하는 start()를 호출해야합니다 :

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

감사합니다. 그랬어. 시간 내 주셔서 감사합니다. – Rodney