Alright, so explaining this situation is somewhat complex. It actually isn't as risque as it seems.
I'm writing a concurrency package which does two things, and it used to work perfectly on JDK 6. The first thing it does is provide a better Future
interface which allows callback when the task completes, using event listeners. "But you can use FutureTask
's done()
for that!" you might say. The problem is that done()
is called immediately when a task is cancelled, while the task might still be doing stuff in its call()
method. Also, cancelling makes it impossible to retrieve partial results. So my own package fixes these issues by extending on the existing packages (including a new thread pool, but most of the implementation is reused there).
The second thing the package does is solve a common GUI problem. Let's say the user clicks "Save" to save an image. If the image is huge, it would be nice to display a progress monitor instead of freezing the interface. But if the document is small, then the sudden flash of a progress monitor confuses users. And we cannot have a minimum popup time - this slows the workflow down. My solution compromises between these two. The effect is that the EDT "freezes" for the time the task takes to complete, or, if it takes longer than say 1 second, displays a progress monitor with a minimum popup time. The effect is rather elegant. This, too, worked perfectly in JDK6, and even worked with several threads.
THE PROBLEM: In JDK7, the freezing part above now gets a subtle bug. A critical assumption of my code is that the Due to an implementation mistake, nevermind.Runnable
passed to SwingUtilities.invokeLater()
will not run concurrently with other event dispatch thread stuff. So the EDT can't be processing button clicks, accelerators, other events, etc, while the Runnable
runs. (This is exploited to stop all input during the freezing) But this seems to have changed in JDK7. In my debugging I noticed the Runnable
might be running while the button pressing code is still running! This quickly causes a deadlock due to later stuff.
Abusing the EDT like this is risky, but back in the day it was the only thing that worked. Some suggested using a GlassPane
to intercept events. But it can't intercepts accelerators. Everything else I tried at the time was also limited in this way.
My question is now if anyone sees a better way to do this. If you think my Future
problem can be solved in a better way, do tell. And most importantly, if you can see a way to solve the GUI problem above, or stop the input, or guarantee the critical assumption I need on JDK, or suggest a long-term solution - all are extremely appreciated. Thanks!