Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.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 是否有一种有效的方法来测试RMI服务器是否已启动?_Java_Rmi - Fatal编程技术网

Java 是否有一种有效的方法来测试RMI服务器是否已启动?

Java 是否有一种有效的方法来测试RMI服务器是否已启动?,java,rmi,Java,Rmi,我有一个RMI客户端测试RMI服务器是否正在运行并且可以访问 此时,我每隔几秒钟执行一次此测试: try { rMIinstance.ping(); } catch (RemoteException e) { getInstanceRegister().removeInstance(rMIinstance); } (ping()是一个简单的虚拟RMI调用。) 如果实例处于脱机状态,我将在大约1分钟后获得 java.net.ConnectException:连接超时 异常,显示服

我有一个RMI客户端测试RMI服务器是否正在运行并且可以访问

此时,我每隔几秒钟执行一次此测试:

try {
    rMIinstance.ping();
} catch (RemoteException e) {
    getInstanceRegister().removeInstance(rMIinstance);
}
ping()
是一个简单的虚拟RMI调用。)

如果实例处于脱机状态,我将在大约1分钟后获得

java.net.ConnectException:连接超时

异常,显示服务器处于脱机状态

然而,代码挂起一分钟,这对我们来说太长了。(我不想更改超时设置。)
是否有方法更快地执行此测试?您可以从计时器中断线程。它有点黑客化,将抛出InterruptedException而不是RemoteException,但它应该可以工作

try {
    Timer timer = new Timer(true);
    TimerTask interruptTimerTask = new InterruptTimerTask(Thread.currentThread());
    timer.schedule(interruptTimerTask, howLongDoYouWantToWait);
    rMIinstance.ping();
    timer.cancel();
} catch (RemoteException | InterruptedException e) {
    getInstanceRegister().removeInstance(rMIinstance);
}
以及TimerTask实现:

private static class InterruptTimerTask extends TimerTask {
    private Thread thread;

    public InterruptTimerTask(Thread thread) {
        this.thread=thread;
    }

    @Override
    public void run() {
        thread.interrupt();
    }

}

受@NeplatnyUdaj答案的启发,我找到了以下解决方案:

try {
     ExecutorService executor = Executors.newSingleThreadExecutor();
     Future<String> future = executor.submit(new Task(rMIinstance));
     System.out.println("Result: "+ future.get(3, TimeUnit.SECONDS));

} catch (RemoteException | TimeoutException e) {
     getInstanceRegister().removeInstance(rMIinstance);
}
试试看{
ExecutorService executor=Executors.newSingleThreadExecutor();
Future=executor.submit(新任务(rminstance));
System.out.println(“结果:+future.get(3,TimeUnit.SECONDS));
}捕获(RemoteException | TimeoutException e){
getInstanceRegister().removeInstance(RMInstance);
}
这项任务是:

class Task implements Callable<String> {
        DatabaseAbstract rMIinstance;
        public Task(DatabaseAbstract rMIinstance)
        {
            this.rMIinstance = rMIinstance;
        }
        @Override
        public String call() throws Exception {
            rMIinstance.ping();
            return "OK";
        }
    }
类任务实现可调用{
数据库抽象实例;
公共任务(数据库抽象实例)
{
this.rminstance=rminstance;
}
@凌驾
公共字符串调用()引发异常{
rMIinstance.ping();
返回“OK”;
}
}

中断发出RMI调用的线程的建议解决方案可能不起作用,这取决于该线程是否处于可以中断的位置。普通正在进行的RMI呼叫不可中断

尝试将系统属性
java.rmi.server.disableHttp
设置为
true
。由于RMI正在故障转移到其HTTP代理机制,因此可能发生长连接超时。此机制在的类文档中进行了描述(尽管非常简短)。(HTTP代理机制在JDK 8中已被弃用)。

将系统属性设置为所需的连接超时(以毫秒为单位)。我也会设置


建议中断线程的答案取决于
java.net
的特定于平台的行为,其行为在被中断时是未定义的。

只是一个小提示:通常您会重用
ExecutorService
,因为它的目的是“缓存”线程。感谢关于中断的提示。超时的问题是,这个VM上的其他RMI实例应该对超时有一定的容忍度。因此,使用适合于其他远程方法的更长超时,并完全去掉这个。如果超时过期,其他方法将抛出异常。我测试了
java.rmi.server.disableHttp
=
true
。这并没有减少长时间的连接超时。哦,好吧,值得一试。当这种情况发生时,听起来您有一个低级连接问题。在尝试RMI之前,请先尝试ping以查看主机是否可访问并作出响应。