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

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

我找不到任何指南来选择正确的条纹数量:
Striped.lazyWeakLock(int stripes)
stripes应该绑定到处理器核的数量还是什么?

最佳答案

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

条纹Lock/Semaphore/ReadWriteLock。这提供了基础
ConcurrentHashMap相似的锁条以可重用的形式存在,
并将其扩展为信号灯和读写锁。 从概念上讲,锁定
strip 化是将锁分成许多条的技术,
增加单个锁的粒度并允许独立
锁定不同条纹并同时进行的操作
为单个锁创建争用的过程。


提供的担保
这个类是相等的键导致相同的锁(或信号量),
即如果是key1.equals(key2),则为striped.get(key1) == striped.get(key2)(假设Object.hashCode()正确实现
键)。请注意,如果key1不等于key2,则不等于
保证striped.get(key1) != striped.get(key2);要素
可能仍会映射到同一锁。 的数量越少
条纹,发生这种情况的可能性越高。


...

在上这堂课之前,可能会想使用Map<K, Lock>,其中K代表任务。 通过将每个唯一键映射到唯一锁,可以最大程度地提高并发性,同时还可以最大程度地减少内存占用。另一方面,一个人可以对所有任务使用一个锁,这样可以最大程度地减少内存占用,并同时降低并发性。 Striped无需选择这些极端之一,而是允许用户在所需的并发性和内存占用量之间进行交易。 例如,如果一组任务受CPU限制,则可以轻松创建非常紧凑的Striped<Lock> of availableProcessors() * 4 strip ,而不是可能在Map<K, Lock>结构中创建数千个锁。


换句话说,Striped提供了一种灵活性,可以根据其哈希码来选择在锁之间分配的多个锁。这允许动态地在并发性和内存占用之间进行权衡,同时保留关键不变性,即key1.equals(key2),然后striped.get(key1) == striped.get(key2)

07-26 08:25