38

我刚刚在看Java的ConcurrentHashMap的源代码,发现这行代码:

/*
 * The maximum number of times to tryLock in a prescan before possibly blocking on acquire in   
 * preparation for a locked segment operation. On multiprocessors, using a bounded number of  
 * retries maintains cache acquired while locating nodes.
 */
static final int MAX_SCAN_RETRIES =
              Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1

用于在MAX_SCAN_RETRIES获取锁时查找条目。我的问题是如何64确定多处理器机器的数量?有人知道这个数字背后的理论64吗?

4

1 回答 1

9

在处理跨多个 CPU 的锁重试时,您需要在尝试快速获取锁(自旋)和允许 CPU 切换到另一个线程以避免浪费 CPU 时间在不会发生的锁上自旋之间取得平衡很快发布。允许 CPU 尝试获得锁的实际自旋次数受到整个系统的实际速度以及通常在临界区中执行的代码量的强烈影响。

这个问题深深植根于停止问题以及与 SMP 系统上的操作系统设计相关的许多其他问题,以优化并发性。这种设计选择通常是通过在许多应用程序中反复试验的方法来解决的。但是,在我看来,选择 64 就像是实现者的任意调用(数字是 2 的幂)。

不幸的是,这个特定的代码既有错误又有限制。错误在于 availableProcessors 的文档指出“此值可能会在虚拟机的特定调用期间发生变化”,因此可能导致锁旋转太多次(如果计数从 > 1 移动到 = 1)或太少(在反之亦然)。它的局限性在于,真正需要在其应用程序中调整并发性的开发人员没有能力这样做,因为 MAX_SCAN_RETRIES 是最终的(尽管可以使用反射来玩一些技巧)。

于 2012-09-04T19:56:52.303 回答