Lock/Semaphore/ReadWriteLock. This offers the underlying lock striping similar to that of
ConcurrentHashMapin a reusable form, and extends it for semaphores and read-write locks. Conceptually, lock striping is the technique of dividing a lock into many stripes, increasing the granularity of a single lock and allowing independent operations to lock different stripes and proceed concurrently, instead of creating contention for a single lock.
The guarantee provided by this class is that equal keys lead to the same lock (or semaphore), i.e.
striped.get(key1) == striped.get(key2)(assuming
Object.hashCode()is correctly implemented for the keys). Note that if
key1is not equal to
key2, it is not guaranteed that
striped.get(key1) != striped.get(key2); the elements might nevertheless be mapped to the same lock. The lower the number of stripes, the higher the probability of this happening.
There are three flavors of this class:
Striped<ReadWriteLock>. For each type, two implementations are offered: strong and weak
Striped<Lock>, strong and weak
Striped<Semaphore>, and strong and weak
Striped<ReadWriteLock>. Strong means that all stripes (locks/semaphores) are initialized eagerly, and are not reclaimed unless
Stripeditself is reclaimable. Weak means that locks/semaphores are created lazily, and they are allowed to be reclaimed if nobody is holding on to them. This is useful, for example, if one wants to create a
Striped<Lock>of many locks, but worries that in most cases only a small portion of these would be in use.
Prior to this class, one might be tempted to use
Map<K, Lock>, where
Krepresents the task. This maximizes concurrency by having each unique key mapped to a unique lock, but also maximizes memory footprint. On the other extreme, one could use a single lock for all tasks, which minimizes memory footprint but also minimizes concurrency. Instead of choosing either of these extremes,
Stripedallows the user to trade between required concurrency and memory footprint. For example, if a set of tasks are CPU-bound, one could easily create a very compact
availableProcessors() * 4stripes, instead of possibly thousands of locks which could be created in a
Source : Google Guava Project Documentation.