我们正在做一些原型设计工作,我们想知道是否有可能中断执行RMI调用的线程。如果我们在这个线程上调用interrupt(),它会抛出InterruptedException吗? (或应该?)我们的测试目前显示它没有。只是想知道它应该如何。
答案 0 :(得分:2)
Interruptible RMI library提供了一种中断RMI调用的机制。通常,当线程调用RMI方法时,线程会阻塞,直到RMI方法返回。如果方法调用花费的时间过长(例如,如果RMI服务器忙,或挂起,或者用户想要取消RMI操作),则没有简单的方法来中断阻塞RMI调用并将控制权返回给RMI线程。可中断的RMI库提供此功能。
该库由两个关键组件组成:RMISocketFactory和ThreadFactory。使用来自RMISocketFactory的套接字从提供的ThreadFactory到RMI接口的线程上的RMI调用可以通过在客户端线程上调用Thread#interrupt()来中断。所以,它真的很容易使用。但请注意,在服务器端,您可能希望添加对方便实用程序方法的调用,以确保当前线程不是已被客户端“中断”的“僵尸”或孤立线程。
以编程方式停止RMI服务器:
RMI服务器启动永不结束的线程。这样服务器在手动关闭之前是持久的。但是,您可以为远程服务器提供远程方法shutDown()
。此方法启动关闭线程。关闭线程仍在等待notify().
当服务器完成所有清理处理时,它会唤醒关闭线程。
关闭线程在两(2)秒延迟后调用System.exit(0)
来结束Java虚拟机。延迟是因为从服务器到发起客户端的消息完成了旅程。
答案 1 :(得分:1)
不,interrupt()
在这里不起作用,因为RMI使用阻塞java.io
,这是不可中断的。
你的选择要么是在一个单独的线程上向服务器发送另一个RMI调用,要求它以编程方式中断处理调用(假设服务器端代码正在执行可中断的循环某种)。
或者在单独的线程中执行原始RMI调用,然后可以根据需要“丢弃”。使用java.util.concurrant.ExecutorService
在这里似乎很有用,因为它允许您提交任务并等待有限的时间来完成它。实际的RMI调用不会被中断,但您的客户端程序仍然可以继续。
答案 2 :(得分:1)
这似乎是RMI 缺少功能。
但是,您可以实现自己的套接字工厂以供RMI使用并超时套接字。我记得我的一些朋友手动操作,但我刚发现Interruptiblermi库自动解决了这个问题。试一试,请告诉我们它的表现。
答案 3 :(得分:1)
java.util.concurrant显然是一个错字,应该是 java.util.concurrent中。
但更重要的是,我没有在任何地方看到java.util.concurrent.ExecutorService。 你的意思是java.util.concurrent.ExecutorCompletionService吗?