Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:在线程中启动进程并获取对已创建进程的引用_Java_Process - Fatal编程技术网

Java:在线程中启动进程并获取对已创建进程的引用

Java:在线程中启动进程并获取对已创建进程的引用,java,process,Java,Process,我有以下集成测试代码,在测试运行之前启动各种服务: @BeforeClass public static void setup() throws Exception { // Set some vars like javaBin location ProcessBuilder builder = new ProcessBuilder(javaBin, "-jar", "app.jar"); Process process = launchProcess(builder); }

我有以下集成测试代码,在测试运行之前启动各种服务:

@BeforeClass
public static void setup() throws Exception {

  // Set some vars like javaBin location

  ProcessBuilder builder = new ProcessBuilder(javaBin, "-jar", "app.jar");
  Process process = launchProcess(builder);

}

private static Process launchProcess(ProcessBuilder builder) throws IOException {

  AtomicReference<Process> process = new AtomicReference<>();
  new Thread(() -> {
    try {
      process.set(builder.start());

      BufferedReader processStd =  new BufferedReader(new InputStreamReader(process.get().getInputStream());     
      BufferedReader processErr = new BufferedReader(new InputStreamReader(process.get().getErrorStream()));

      // To prevent deadlocks due to limited buffer size
      String s = "";
      while(processStd .readLine() != null) {}
      while((s = processErr .readLine()) != null) {
          System.err.println(s);
      }
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }).start();

  return process.get();
}
@BeforeClass
public static void setup()引发异常{
//设置一些变量,比如javaBin location
ProcessBuilder=newProcessBuilder(javaBin,“-jar”,“app.jar”);
过程=启动过程(生成器);
}
私有静态进程启动进程(ProcessBuilder生成器)引发IOException{
AtomicReference进程=新的AtomicReference();
新线程(()->{
试一试{
process.set(builder.start());
BufferedReader processStd=新的BufferedReader(新的InputStreamReader(process.get().getInputStream());
BufferedReader ProcessError=新的BufferedReader(新的InputStreamReader(process.get().getErrorStream());
//防止由于缓冲区大小有限而导致死锁
字符串s=“”;
而(processStd.readLine()!=null){}
而((s=processErr.readLine())!=null){
系统错误打印项次;
}
} 
捕获(IOE异常){
e、 printStackTrace();
}
}).start();
返回进程get();
}

进程启动正常,但我
process.get()
始终返回
null
。我做错了什么?如何使用上述方法获取对已启动进程的引用?如果我在
setup()
函数本身中设置进程,即
process=builder.start()
,那么它就可以正常工作。但是,这也会导致大量重复,因为我需要在不同的JVM中启动许多不同的服务。

问题很可能是,当您在
启动过程
结束时返回
process.get()
时,线程还没有真正启动

在从方法返回之前,您需要等待线程实际启动并执行对
process.set(builder.start())
的调用

这可以通过像
倒计时闩锁这样简单的方法来实现

private static Process launchProcess(ProcessBuilder builder) throws IOException {
  final CountDownLatch latch = new CountDownLatch(1);
  // ...
  new Thread(() -> {
    try {
      process.set(builder.start());
      latch.countDown();
      //...
    } catch (IOException e) {
      //...
    }
  }).start();

  latch.await();
  return process.get();
}

问题很可能是,当您在
launchProcess
结束时使用
process.get()
返回时,线程尚未实际启动

在从方法返回之前,您需要等待线程实际启动并执行对
process.set(builder.start())
的调用

这可以通过像
倒计时闩锁这样简单的方法来实现

private static Process launchProcess(ProcessBuilder builder) throws IOException {
  final CountDownLatch latch = new CountDownLatch(1);
  // ...
  new Thread(() -> {
    try {
      process.set(builder.start());
      latch.countDown();
      //...
    } catch (IOException e) {
      //...
    }
  }).start();

  latch.await();
  return process.get();
}

在线程实现之前和之后移动
process.set(builder.start());
如果使用单独线程的唯一原因是使用进程的输出,则可以使用
builder.inheritIO().start()替换整个launchProcess方法
.move
process.set(builder.start());
在线程实现之前和之后
AtomicReference process=new AtomicReference();
如果使用单独线程的唯一原因是使用进程的输出,则可以使用
builder.inheritIO().start()替换整个launchProcess方法
。谢谢,我已经尝试了这两种方法和
未来的
实现。虽然这两种方法都成功地等待进程启动,但在我启动它们时,所有进程都已
hasExited=true
。在这种情况下,如何防止线程退出?我只需要一个对正在启动的进程的引用已启动。是否有任何原因需要在单独的线程中启动此程序?如果需要该线程,则需要通过在process Object上调用
waitFor
使线程等待进程完成。在单独的线程中启动这些程序的主要原因是能够使服务并行启动和运行,即不需要必须等待它们各自单独启动。我将尝试一下
waitFor
方法。我们最终只编写了一个shell脚本来执行各自项目中的
jar
文件。它比提供的用例简单得多,但满足了我们的需要。我仍然会将此标记为一个答案,因为它确实是这样做的回答这个问题。谢谢,我已经尝试了这两种方法和
未来
实现。虽然这两种方法都成功地等待进程启动,但在我启动它们时,所有进程都已
hasExited=true
。在这种情况下,我如何防止线程退出?我只需要对进程的引用已启动。是否有任何原因需要在单独的线程中启动此操作?如果需要该线程,则需要通过调用process Object上的
waitFor
,让该线程等待进程完成。在单独的线程中启动它们的主要原因是能够启动服务并并行运行,即.e.不必等待它们各自独立启动。我将尝试一下
waitFor
方法。我们最终只编写了一个shell脚本来执行各自项目中的
jar
文件。它比提供的用例简单得多,但满足了我们的需要。我仍然会像在中一样将此标记为一个答案请回答这个问题。