I Have a Thread which should be run synchronously to the SWT GUI Thread, but with a timeout that kills the thread if it isn't done after 10 seconds. EDIT: I am required to remain compatible with Java 1.4.
Thread:
private boolean isFinished;
(...)
isFinished = false;
Thread t = new Thread ("getShellsThread") {
public void run() {
try {
logger.debug("aquirerootcont SWT entered - " + Thread.currentThread().toString());
(...)
} finally {
isFinished = true;
logger.debug ("hasShells is Finished!");
}
}
}
Timeout code:
long startTime = System.currentTimeMillis();
long timeWaited;
((Display)displays.get(i)).asyncExec (t);
while(!isFinished){
timeWaited = System.currentTimeMillis() - startTime;
logger.debug("aquireRootContainer: timeWaited: " + timeWaited);
if (timeWaited > 1000) {
logger.debug(t +" Name: " + t.getName()+" took to long and will be destroyed!");
t.interrupt ();
shell = null;
break;
}
}
This code is working for Windows 7 and Windows 8 with JRE 1.6 and 1.7 as well as IBM JREs. However, for Windows XP, while IBM JRE works just fine, JRE 1.6_45 will not.
The Logs on XP 1.6_45 are showing that the Thread does nothing and after 10 seconds says:
Thread[getShellsThread,10,RMI Runtime] Name: getShellsThread took to long and will be destroyed!
Windows Taskmgr says that the rmiregistry.exe has been killed.
Why does this code kill the RMI on one particular system? Any clues would be great!
Due to required backward compatibility, most of the Methods that are used nowadays for timeout threads are unfortunately not available.
There is a serious conceptual mistake in your code
Thread t = new Thread ("getShellsThread") {
};
....
((Display)displays.get(i)).asyncExec (t);
The Display.asyncExec
method takes a Runnable
as an argument. You are passing at a Thread
. If you do that, the method is not going to call your Thread object's run()
method on some other thread.
Your thread object t
is never actually started, so when you call t.interrupt()
in the timeout code nothing happens. Certainly you are not interrupting the thread that is actually running the run()
method.
Further to that, I suspect that using Display.asyncExec
to run a potentially long running task is a bad idea. On reading the javadoc, it is clear that asyncExec runs the task on the SWT user-interface thread for the display. While it is running, the UI thread won't be able to process events from the user's mouse movements, key strokes and so on. The UI will "freeze".
And finally, your timeout code is actually a busy loop which will burn CPU cycles until the timeout expires. That is poor design.
I think the correct solution is to get rid of the asyncExec(t)
call, and instead call t.start()
to start the thread. Then replace the wasteful busy-waiting code you are using to implement the timeout. Instead, implement the timeout using the TimerTask
class. It was introduced in Java 3 so it should be available on your legacy platform.