I finished porting my open source SWT game to Linux recently. One of the final steps was to resolve a deadlock that occurred in Linux but did not occur in Windows or Mac.
The implementation of SWT on Linux uses an implicit lock that isn’t present on Windows and Mac. This means that you will get fewer SWT runtime errors on Linux. But it also means that it’s easier to deadlock on Linux.
When porting my SWT app to Linux, this implicit SWT lock was interacting with some synchronized methods in my application that resulted in deadlock.
In the cases where I was synchronizing methods, I didn’t actually need method synchronization–I just needed to ensure that only one thread was ever in that method at a time–if there was already a thread in that method, it was ok for the next caller to balk.
So I set out to determine how to find out whether any thread is locking a particular monitor. This turned out to be way harder than I expected. As near as I can tell, the only way to do this right now is to loop through all the threads and ask each one: “are you locking my monitor?” Not the kind of thing you want to put in a Canvas painting event handler.
Then I happened upon the new Java 5 java.util.concurrent.locks library. Beautiful stuff! I removed my “synchronized” method modifiers and replaced them with calls to a ReentrantLock. In the case where it’s okay to balk, I just call trylock() instead of lock(). trylock() will return true or false indicating whether it succeeded in grabbing the lock.
This solved my deadlock problem and the game now runs on Linux!