我想使用Guava Striped Lock提供对资源的锁定访问。例如
Striped<Lock> keyLocks = Striped.lazyWeakLock(10)
Lock lock = keyLocks.get("resourceId")
// use lock...
我找不到任何指南来选择正确的条纹数量:
Striped.lazyWeakLock(int stripes)
stripes
应该绑定到处理器核的数量还是什么?
答案 0 :(得分:0)
没有一般的经验法则,它取决于并发级别和内存消耗之间的权衡。 Striped
JavaDoc部分解释了它:
条纹
Lock/Semaphore/ReadWriteLock
。这提供了基础 类似于ConcurrentHashMap
的可重复使用形式的锁条, 并将其扩展为信号灯和读写锁。 从概念上讲,锁定 条带化是将锁分成许多条的技术, 增加单个锁的粒度并允许独立 锁定不同条纹并同时进行的操作 为单个锁定创建争用。提供的保证 这个类是相等的键导致相同的锁(或信号量), 即如果
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限制,则可以轻松创建非常紧凑的{ {1}}条带,而不是可能在Striped<Lock> of availableProcessors() * 4
结构中创建的数千个锁。
换句话说,Map<K, Lock>
提供了一种灵活性,可以根据其哈希码来选择在锁之间分配的多个锁。这样可以动态地在并发性和内存占用之间进行权衡,同时保留如果Striped
则为key1.equals(key2)
的关键不变性。