Sometimes, you want to synchronize on a transient object - a resource that isn't going to stay in memory.

For example, there is nothing in the Servlet 2.5 MR6 specification that says a HttpServletSession instance can't be recreated as a facade object every time it is requested. That makes the session instance a poor candidate for a synchronized lock. There is nothing in the specification that prevents the container implementer from always serializing session attributes as soon as they are set either. That makes session attributes poor candidates for synchronization locks. Note: existing implementations may support either of these approaches in practice, but lets say our imaginary servlet container doesn't. However, the session ID will be consistent across requests.

The following code allows you to get an object to synchronize on based on a String ID. This allows a mutual exclusion lock (mutex).

This code isn't a panacea. Any code that requests a Mutex object will pass through the global synchronization block within the class. For trivial synchronization blocks, the cost of getting the object will outweigh locking on a global object.

Notes:

A WeakHashMap is used to reference the Mutex instances. This avoids the need to release the object - the garbage collector will get rid of it as long as you don't keep a hard reference to it.

The WeakHashMap values have hard references, so the Mutex value is wrapped in a WeakReference.

Are you talking about changing IdMutexProvider.getMutex(String) to IdMutexProvider.getMutex(StringBuffer)? Yes, this would be a bad idea. The implementation is dependent on the argument being a String.

I seem to recall trying to synchronize based on .equals rather than == in java because I wished the scope of the mutext to be based on a "combined key". If I recall correctly, the WeakHashMap was not suitable because the keys had weak references when one needed the soft references to the values to get the desired behavior. Apache collections had a Map implementation that allowed you to specify whether you wanted hard, soft, weak references on both keys and values. Hard keys and Soft values seemed to be the one that passed the unit tests.

This post is nearly 5 years old at this point, but I thought I'd chime in with my experiences using the example.

Under load we found that the "synchronized(mutexMap)" portion of getMutex was too much of a bottle neck. There is likely a way to optimize this code, but we ended up going another direction and placing a single mutex in a context object.

Disclaimer

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.