我在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.
}
你有什么建议吗? 谢谢。
答案 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