This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Background: I am working on a very large Java/Swing application. We have many threads at work for a lot of our code. One component is a cache manager that remembers data retrieved from our server. If the network goes away, the cache manager needs to ask the user if they want to use the old data or cancel the transaction. I wrote a "choice manager" because we had several questions like this we needed to prompt the user for a decision.
The Choice Manager class has a synchronized method that does the prompting, or if the user has checked a previous "Don't ask me again" choice, just returns an action immediately. This method checks to see if it is on the EventDispatcherThread (EDT) and if so does the processing. If not, it does an invokeAndWait() to switch threads and prompt the user.
The deadlock happens right after a restart with the network disabled. Many components ask to reuse cached data at about the same time. My theory is that one of the slower of these components is running on the EDT and that thread is held up waiting for that component to get into my method. The code in the method is waiting for the EDT so it can do the Dialog to ask the user.
It seems the only solution is to make sure that none of the callers of this method are on the EDT to start with. Does that make sense?
Thanks for the note. I made it synchronized so you would never get 8 popup dialog boxes at once (which might happen if the method was not synchronized). We figured it would annoy the users to get a stack of popups at once.
I guess the tradeoff is that with the stack of popups they would not get any hangs or deadlocks. Groan.