Guava Striped 的正确条纹数是多少?

What is the proper number of stripes for Guava Striped?

我想使用 Guava Striped Lock 提供对资源的锁定访问。例如

Striped<Lock> keyLocks = Striped.lazyWeakLock(10)
Lock lock = keyLocks.get("resourceId")
// use lock...

我找不到任何关于如何选择正确条纹数量的指南:

Striped.lazyWeakLock(int stripes)

stripes应该绑定处理器核心数还是什么?

没有一般的经验法则,它取决于并发级别和内存消耗之间的权衡。 Striped JavaDoc 对其进行了部分解释:

A striped Lock/Semaphore/ReadWriteLock. This offers the underlying lock striping similar to that of ConcurrentHashMap in 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. if key1.equals(key2) then striped.get(key1) == striped.get(key2) (assuming Object.hashCode() is correctly implemented for the keys). Note that if key1 is 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.

...

Prior to this class, one might be tempted to use Map<K, Lock>, where K represents 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, Striped allows 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 Striped<Lock> of availableProcessors() * 4 stripes, instead of possibly thousands of locks which could be created in a Map<K, Lock> structure.


换句话说,Striped 为 select 多个锁提供了灵活性,这些锁根据它们的哈希码分布在键之间。这允许在并发性和内存占用之间动态应用权衡,同时保留关键不变性,即如果 key1.equals(key2),则 striped.get(key1) == striped.get(key2)