Is it possible to interrupt a Java RMI call?
We're doing some prototyping work and we're wondering if it is possible to interrupt a thread that performed an RMI call. If we call interrupt() on this thread, would it throw an InterruptedExcept开发者_如何学编程ion? (or should it?) Our testing currently shows it doesn't. Just wondering how it should be.
The Interruptible RMI library provides a mechanism to interrupt RMI calls. Typically when a thread invokes an RMI method, the thread blocks until the RMI method returns. If the method call is taking too long (e.g. if the RMI server is busy, or hangs, or if the user wants to cancel the RMI operation), there is no easy way to interrupt the blocking RMI call and return control to the RMI thread. The Interruptible RMI library provides this functionality.
The library consists of two key components: an RMISocketFactory and a ThreadFactory. RMI calls made on a thread from the provided ThreadFactory to an RMI interface using sockets from the RMISocketFactory can be interrupted by calling Thread#interrupt() on the client thread. So, it's really easy to use. But note also on the server side that you may wish to add a call to a handy utility method to ensure that the current thread isn't a "zombie" or orphaned thread that has already been "interrupted" by the client.
Stopping a RMI server programmatically :
RMI Servers start a thread that never ends. This is so that the Server is persistent until manually shut down. However, you can provide a remote method, shutDown()
, for the Remote Server. This method starts a shutdown thread. The shutdown thread remains waiting for a notify().
When the Server finishes all clean-up processing it wakes up the shutdown thread.
The shutdown thread, after a two (2) second delay, calls System.exit(0)
to end the Java Virtual Machine. The delay is so that messages from the Server to the initiating Client complete the journey.
No, interrupt()
won't work here, since RMI uses blocking java.io
, which is non-interruptable.
Your options are either to send another RMI call to the server on a separate thread, which asks it to interrupt the processing the call programmatically (assuming the server-side code is performing an interruptible loop of some kind).
Alternatively perform the original RMI call in a separate thread, which you can then "discard" if required. Using a java.util.concurrant.ExecutorService
would seem useful here, since it allows you to submit a task and wait for a finite time for it to complete. The actual RMI call wouldn't be interrupted, but your client program could still continue.
This seems to be a RMI missing feature.
You might however implement your own socket factory to be used by RMI and timeout the sockets. I remember some of my friends were doing it manually, but I just found Interruptiblermi library that addresses this issue automatically. Give it a try and please tell us how it performs.
java.util.concurrant is clearly a typo, which should be java.util.concurrent.
But more importantly, I don't see java.util.concurrent.ExecutorService anywhere. Did you mean java.util.concurrent.ExecutorCompletionService ?
精彩评论