Here’s a hacky technique that is preventing a particular deadlock in the MMORPG client.
Due to Java’s AWT painting rules, the AWT/Swing thread must be used when painting components. Unfortunately, I’ve introduced thread contention between the AWT thread and the world Rendering thread. In the right circumstance, these threads deadlock on each other (each holds a lock the other needs).
The real solution is to resolve the contention. Putting this off for a rainy day, I’ve implemented a quick-and-dirty deadlock avoidance approach. First, note that I’m using the elegant java.util.concurrent.locks API (rather than synchronized keyword). I must acquire a lock within my JPanel’s paintComponent(Graphics g) method. Instead of calling Lock.lock(), call Lock.tryLock(timeout) with some arbitrary (short) timeout. If the Rendering and AWT threads are deadlocked, the AWT thread will soon release its resources and the Rendering can continue.
Leveraging the passive nature of AWT painting, the failed attempt is re-dispatched by calling repaint(clip) (passing the clipping region of the original paint request). Hopefully, the thread contention is cleared up on the subsequent paintComponent. If not, this technique risks forever requesting repaints (more logic could catch this and trigger client failure, or maybe try to restart the Rendering engine).
Debugging shows this happens rarely, but cleans up nicely. There is the potential to leave some graphic artifacts when the AWT paint fails, but this is tolerable for now. In any case, this hacky fix is better than the client locking up.
Correct: No. Elegant: Almost. Clever: Barely. Recommended: Absolutely not.

