2009-08-07 4 views
2

나는 스레드에 대한 작업에 익숙하지 않아서 누군가가이 작업을 수행하는 가장 좋은 방법을 찾도록 도와 줄 수 있기를 바랍니다.스레드와 ProcessBuilder 사용하기

내 Java 응용 프로그램에 JButton이 있습니다 ... 버튼을 클릭하면 일부 외부 파이썬 코드를 실행하는 프로세스를 만드는 프로세스 작성기가 있습니다. 파이썬 코드는 일부 파일을 생성하며 시간이 좀 걸릴 수 있습니다. 파이썬 코드 실행이 끝나면 Java 어플리케이션 내 애플릿에 해당 파일을로드해야합니다.

현재 양식에서 외부 파이썬 파일을 호출하는 코드 내에 p.waitFor()가 있습니다 ... 버튼을 클릭하면 버튼이 멈 춥니 다 (전체 응용 프로그램이 실제로 멈춤) 수행. 분명히, 나는이 프로세스가 진행되는 동안 사용자가 나머지 응용 프로그램과 상호 작용할 수 있기를 원하지만, 완료되면 응용 프로그램에 애플릿을로드 할 수 있도록 응용 프로그램에 알리고 싶습니다. .

가장 좋은 방법은 무엇입니까?

도움 주셔서 감사합니다.

답변

9

SwingWorker을 사용하여 백그라운드 스레드에서 파이썬 프로세스를 호출해야합니다. 이렇게하면 장시간 실행되는 작업이 실행되는 동안 UI가 응답 성을 유지합니다.

// Define Action. 
Action action = new AbstractAction("Do It") { 
    public void actionPerformed(ActionEvent e) { 
    runBackgroundTask(); 
    } 
} 

// Install Action into JButton. 
JButton btn = new JButton(action); 

private void runBackgroundTask() { 
    new SwingWorker<Void, Void>() { 
    { 
     // Disable action until task is complete to prevent concurrent tasks. 
     action.setEnabled(false); 
    } 

    // Called on the Swing thread when background task completes. 
    protected void done() { 
     action.setEnabled(true); 

     try { 
     // No result but calling get() will propagate any exceptions onto Swing thread. 
     get(); 
     } catch(Exception ex) { 
     // Handle exception 
     } 
    } 

    // Called on background thread 
    protected Void doInBackground() throws Exception { 
     // Add ProcessBuilder code here! 
     return null; // No result so simply return null. 
    } 
    }.execute(); 
} 
+0

정말 감사합니다 ... 나는 하나의 가능한 접근 방법을 설명 할 것이다 생각의 log4j 로거의 존재를 가정합니다 몇 가지 예제 코드입니다. SwingWorker가 존재한다는 것도 알지 못했지만 완벽하게 작동했습니다. – knt

0

새 프로세스 모니터링을위한 새로운 스레드를 만들고 싶습니다. 당신이 발견 한 것처럼, UI에 하나의 스레드를 사용하고 자식 프로세스를 모니터링하면 자식 프로세스가 실행되는 동안 UI가 멈춘 것처럼 보입니다.

여기

Runtime runtime = Runtime.getRuntime(); 
String[] command = { "myShellCommand", "firstArgument" }; 

try { 

    boolean done = false; 
    int exitValue = 0; 
    Process proc = runtime.exec(command); 

    while (!done) { 
     try { 
      exitValue = proc.exitValue(); 
      done = true; 
     } catch (IllegalThreadStateException e) { 
      // This exception will be thrown only if the process is still running 
      // because exitValue() will not be a valid method call yet... 
      logger.info("Process is still running...") 
     } 
    } 

    if (exitValue != 0) { 
     // Child process exited with non-zero exit code - do something about failure. 
     logger.info("Deletion failure - exit code " + exitValue); 
    } 

} catch (IOException e) { 
    // An exception thrown by runtime.exec() which would mean myShellCommand was not 
    // found in the path or something like that... 
    logger.info("Deletion failure - error: " + e.getMessage()); 
} 

// If no errors were caught above, the child is now finished with a zero exit code 
// Move on happily 
+0

Swing을 암시하는 JButton에 대해별로 생각하지 못했습니다. SWT 또는 콘솔 앱과 동등하게 작동하는 다소 일반적인 접근법입니다 ... – jharlap

+0

새 스레드를 만들어야하지만 사용자 예제에서는 이. [ProcessBuilder] (http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html)도 사용해야합니다. –

관련 문제