Ok, you’re wondering, what the hell is a Keyed Mutex. Understandable. Well, you see, it’s something I made up. Don’t get me wrong, I’m not claiming I invented anything – I’m sure something like this already exists, I just don’t know what it’s called or how to find it. So I made my own. Perhaps a little background would help.
I was anticipating a project that would require me to accept messages via socket and process them. The processing of each message could take up to a half a second so I wanted to provide a thread pool which would queue requests and process them concurrently. This would allow timely response to the socket client and multi-tasked processing of the messages. Note: this code would not be running in a JEE container where I could design something lovely like a JMS queue backed by a pool of Message Driven Beans.
One catch with my design was that each message represented a unique part number and it was imperative that two messages for the same part never be processed at the same time. What I needed was a reentrant mutex that was specific to each unique part number. This would allow the processing code to acquire a lock on the mutex for that part and cause any other messages for the same part to block until processing was completed.
I did some Internet searches but didn’t find anything that worked exactly like this. Oh sure, I could have used the ReeentrantLock class from Doug Lea’s util.concurrent library coupled with a HashMap but there were a couple of cons to this approach:
- It would have required including yet another third party library as this codebase was not yet under Java 5 where the concurrency classes are built in.
- I wanted the Map of mutexes to be dynamic. In other words be I wanted mutexes freed when not being used by any thread. Doug’s ReentrantLock class provides a way to determine how many locks the current thread has acquired but does not provide a good mechanism for determine how many threads are waiting on the lock. As a result I would never know if it was safe to discard the mutex object.
- I wanted to consolidate this functionality in a KeyedMutexManager that was easy to use and hide any complexity.
- I thought the world might someday need a mediocre Keyed Mutex class library. Ok, not really, but I do love to code and usually jump at any opportunity.
As things turned out the project I envisioned using this tool with was pushed out into the future but I thought I’d release the code in case it might help someone.
So, how does a Keyed Mutex work? Pretty simple really. When you have a thread that wishes to synchronize based on a unique String value you call KeyedMutexManager.lock(key). The KeyedMutexManager instance may be allocated globally and shared by all threads or instantiated by each thread. KeyedMutexManager works from a static HashMap so either approach provides the same result.
For example a thread uses KeyedMutexManager as follows:
public void run()
KeyedMutexManager mutexMgr = new KeyedMutexManager();
final Msg msg = getNextMsg();
Sorry for the long winded explanation. You can get the code here.