番石榴条纹的正确条纹数是多少?

And*_*gin 6 java concurrency locking guava

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

Striped<Lock> keyLocks = Striped.lazyWeakLock(10)
Lock lock = keyLocks.get("resourceId")
// use lock...
Run Code Online (Sandbox Code Playgroud)

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

Striped.lazyWeakLock(int stripes)
Run Code Online (Sandbox Code Playgroud)

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

Mik*_*kov 0

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

有条纹的Lock/Semaphore/ReadWriteLock。这提供了类似于ConcurrentHashMap可重用形式的底层锁条带化,并将其扩展为信号量和读写锁。从概念上讲,锁条带化是将锁划分为多个条带的技术,增加单个锁的粒度,并允许独立操作锁定不同的条带并并发执行,而不是为单个锁创建争用。

该类提供的保证是相同的键导致相同的锁(或信号量),即 if key1.equals(key2)then 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条带,而不是在Map<K, Lock>结构中创建数千个锁。


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

  • 这并不能回答我的问题。JavaDoc 中很清楚关于条纹的总体思路。问题是关于实际使用。 (2认同)