Interrupting a Thread in a Remote Object?
843793Nov 9 2004 — edited Nov 10 2004HI,
I am trying to get some thread synchronization to happen between a client and a remote RMI object. Essentially what I am trying to accomplish, is that if I interrupt a call on a blocking method in the remote object, I want the thread to throw the InterruptException. For example, the following code represents what I am trying to accomplish:
package bca.test.rmi;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class InterruptThreadApp {
RemoteBlockingObjectInt remote = null;
public static void main(String[] args) throws Exception {
//Create the remote object
RemoteBlockingObject obj = new RemoteBlockingObject();
//bind it to the registry
Naming.rebind("rmi://localhost/blocking", obj);
//start the client, or the thread which will access the blocking call remotely
InterruptThreadApp app = new InterruptThreadApp();
Thread blocking = null;
//wait for the thread to start
synchronized ( app ) {
blocking = app.startClient();
app.wait();
}
Thread.sleep(2000);
//now interrupt the thread (note: the remote object should be blocking in
//the blockingMethod().. this should produce an InterruptException?
blocking.interrupt();
}
public Thread startClient() {
Thread t = new Thread("Client") {
public void run() {
try {
//get a handle to the stub
remote = (RemoteBlockingObjectInt) Naming.lookup("rmi://localhost/blocking");
//now make a call to the blocking method, but first wake up the client
synchronized ( InterruptThreadApp.this ) {
InterruptThreadApp.this.notify();
}
//now make the blocking call
remote.blockingMethod();
}
catch (InterruptedException e) {
System.out.println("WooHoo! This is what we want! But it never gets thrown :(");
}
catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
return t;
}
}
package bca.test.rmi;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.Remote;
public class RemoteBlockingObject extends UnicastRemoteObject implements RemoteBlockingObjectInt {
Object obj = new Object();
public RemoteBlockingObject() throws RemoteException {
super();
}
public void blockingMethod() throws RemoteException, InterruptedException {
synchronized (obj) {
System.out.println("About to block.. so we can be interrupted later");
obj.wait();
}
}
}
interface RemoteBlockingObjectInt extends Remote {
public void blockingMethod() throws RemoteException, InterruptedException;
}
When I make a call to "remote.blockingMethod()", it blocks in the remote object (buy just "wait" ing). I want to interrupt this thread, by issuing an Thread.interrupt(). When I do so (I call "blocking.interrupt()"), nothing happens... no exception is thrown.. it just silently fails.
Ok, so I suppose that we can not interrupt a remote thread.. that is fine. But what if I want to interrupt the RMI thread making the remote call? I don't want it to block forever. How can I "cancel" the remote call?
Ideally, I would like the remote.blockingMethod() call to throw an InterruptException when I issue an "interrupt()" on the blocking thread. Any suggestions on how I might accomplish this?
Thanks,
Bryan