如果线程中没有Java中的公共数据,如何在线程之间指定通知

时间:2010-11-21 20:17:00

标签: java multithreading

我在Java中有一个线程,它启动HttpService

ProcessBuilder pb = new ProceeBuilder(command);
Process process = pb.start();
process.waitFor();

我有另一个线程来检查服务是否已启动。

while (result != 0) {
  ServerSocket socket = new ServerSocker(port);
  socket.close();
  result = 0
  catch (BindException be) {
    result = 1;
  }
}

现在,我需要以某种方式获取有关服务是否未能启动或成功启动的信息。我需要将它返回到Main类,它启动这两个线程以继续。像

这样的东西
while (!started || !failed) {
     wait for getting information from the threads.
}

你有什么建议吗? 谢谢。

3 个答案:

答案 0 :(得分:1)

如何使用传递给两个线程的回调?

(省略试试)

public class MyCallback {
  private Boolean processSuccess;
  private Boolean serviceSuccess;
  public synchronized void notifyProcessStart(boolean success) {
    this.processSuccess = success;
    this.notifyAll();
  }
  public synchronized void notifyServiceCheck(boolean success) {
    this.serviceSuccess = success;
    this.notifyAll();
  }
  public synchronized void waitForResult() {
    while(processSuccess == null || serviceSuccess == null) {
      this.wait();
    }
    // ... do something good
  }
}

答案 1 :(得分:0)

我很抱歉,但我担心检查该服务的代码是否有错误。 此代码运行速度非常快,启动服务器套接字并立即关闭它。如果你的意思是这个线程应该在进程开始时退出,听同一个端口是错误的。您的进程有50%的机会成功启动而其他50%失败,因为当它试图开始收听端口时,看门狗正在侦听同一个端口本身。

所以,我相信您应该尝试使用ProcessBulder运行进程(正如您所做的那样),然后启动延迟看门狗任务,尝试连接到此端口,即

private boolean isServiceRunning() {
    int port = 123;
    try {
        new Socket("localhost", port).close();
        return true;
    } catch (IOException e) {
        return false;
    }
}

应该从单独的线程调用此方法。实现线程的最佳方法是使用一些工具为您完成。在这种情况下,java.util.Timer是最佳选择。我建议运行定期任务,调用我们的方法isServiceRunning(),如果result为true则取消自己:

    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            if(isServiceRunning()) {
                this.cancel();
            }
        }

    }, new Date(), 10000);

但如果这个解决方案不适合你,我建议你使用wait()和notfify()实现线程间通信。不要忘记两者都必须处于同步块中。 祝你好运!

答案 2 :(得分:0)

您可以尝试使用布尔标志。调整您的示例代码:

主题1:

ProcessBuilder pb = new ProcessBuilder(command); 
Process process = pb.start();
process.waitFor();
if(!wasConnectionEstablished()) {
     setConnectionFailed(true);
}

主题2:

while ((result != 0) && (!isConnectionFailed())) {        
    ServerSocket socket = new ServerSocker(port);        
    socket.close();        
    result = 0        
    catch (BindException be) {        
        result = 1;
        wait(timeout);
    }
}
if(isConnectionFailed()) 
   throw new ConnectionFailedException();
else setConnectionEstablished(true);
//continue normal execution