2011-05-12 85 views
4

我是java新手。我负责编写Java程序来运行命令行。我在DOS提示符下测试了命令行,因为我还没有访问Linux的盒子。它工作得很好。有关完整的命令行语法,请参阅下面的PROGRAM。该作业将需要6个输入文件并生成一些输出文件。接下来,我尝试创建一个类并使用getruntime和过程来处理这个工作。即使它编译没有错误,但是当我运行它只显示光标闪烁...我想我需要使用线程异步技术。请提供一些建议,因为我没有足够的时间来完成这些项目。我还想在作业完成时实施回调或返回值。一个例子将不胜感激。由于如何在java中使用线程异步运行命令行

import java.io.*; 
public class RunJob { 

// public static final String PROGRAM = "c:\\wrk\\java.exe Hello"; 

//one command line below 
public static final String PROGRAM = "c:/java.exe -cp \"wrk/jmp.jar;wrk/colt.jar\" gov.lanl.yadas.reliability.UltimateMissileReliabilityModel 10000 \"wrk/\" x1.dat x2c.dat x3.dat x4.dat x5.dat x6.dat true"; 

// Set to true to end the loop 
static boolean done = false; 

public static void main(String argv[]) throws IOException { 

    BufferedReader is; 
    String line; 
    String returnMsg = "Start "; 
    final Process p = Runtime.getRuntime().exec(PROGRAM); 
    System.out.println("start"); 


    Thread waiter = new Thread() { 
     public void run() { 
     try { 
      p.waitFor(); 
     } catch (InterruptedException ex) { 
     System.out.println("InterruptedException"); 
      return; 
     } 
     System.out.println("Program terminated!"); 
     done = true; 
     } 
    }; 
    waiter.start(); 
    is = new BufferedReader(new InputStreamReader(p.getInputStream())); 

    while (!done && ((line = is.readLine()) != null)) 
     { 
     System.out.println(line); 
     returnMsg = returnMsg + line;  
     } 
     System.out.println(returnMsg); 
     System.out.println("End"); 

    return; 
    }// main 


} 

回答

3

我认为有,为什么你想从另一个java程序运行Java程序,而不是仅仅从一个shell脚本,或通过调用的API一个很好的理由 - 但如果没有 - 请重新考虑。

至于你的问题 - 如果你的应用程序产生大量的输出(你作为一个进程运行的那个) - 你的应用程序将挂起。 p.waitFor()将暂停,直到过程结束。但是如果你没有阅读InputStream的信息 - 它会溢出并挂起!

建议#1:将p.waitFor()放在最后。
建议#2:读这个article。如果我没有记错的话,那是我遇到类似问题时所阅读的那个。你也可以谷歌“StreamGobbler” - 这是一个单独的线程“吞噬”你的流的通用名称。
建议#3:不要忘记ErrorStream - 如果您的应用程序会产生太多的错误 - 该流也会导致进程挂起。