Let’s say you have a set of keys, and you want to lock on a per-key level. A naive solution could look like this:

However, there’s quite a few things wrong with this:

It has the potential to use a LOT of memory. (if we have high key cardinality)

We need to lock BOTH the map AND the key lock. (If we had mutability a la ConcurrentHashMap , we could get around this, but that’d be un-Scala-like.)

, we could get around this, but that’d be un-Scala-like.) We keep creating keys and destroying keys. If we didn’t destroy keys and keys weren’t often reused, we’d OOM.

Code is inevitably messy due to all of the above.

The thing is, we usually don’t need all resources to be accessible simultaneously. People rarely do. Thus, we can create a locking system using the mod of a hash, similar to a hash table, where each “bucket” is simply a lock. This is also known as lock striping.

With this strategy in mind, we can rewrite the above class like so:

Note that we’ve fixed quite a few problems:

We are fixed to a known amount of memory.

We don’t need to lock the list of locks, as we’re only performing reads. (Also Scala enforces immutability on Vector , yay!)

, yay!) We can “get” a lock, since locks are never deleted.

We allocate all of the locks upfront, so GC can’t screw us over. This also hugely simplifies our code.

The only downside to this is that each lock could possess multiple keys, though you can probably tweak the numbers to find something with a good balance of throughput and memory usage.

Further reading