我想使用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)
。