Java ConcurrentHashMap实现

我只是看着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 

获取locking时, MAX_SCAN_RETRIES用于查找条目。 我的问题是如何确定一个多处理器机器64号? 有人知道64号背后的理论吗?

在处理跨多个CPU的锁重试时,在尝试快速获取锁(旋转)和允许CPU切换到另一个线程以避免浪费CPU时间(不会旋转锁)即将发布。 一个CPU试图获得一个锁的实际的自旋次数受整个系统的实际速度以及通常在关键部分内执行的代码量的强烈影响。

这个问题在停止问题以及与SMP系统上关于优化并发性的OSdevise有关的许多其他问题上有着深刻的根源。 这种deviseselect通常是通过对许多应用程序进行反复试验来解决的; 但是64的select在我看来就像执行者的任意调用(数字是2的幂)。

不幸的是,这个特定的代码是错误的和限制。 问题在于availableProcessors的文档中声明“这个值在虚拟机的特定调用期间可能会改变”,因此可能会导致锁太多旋转(如果计数从> 1移动到= 1)或太less(在反之亦然)。 这是一个限制因素,真正需要调整应用程序并发性的开发人员无法做到这一点,因为MAX_SCAN_RETRIES是最终的(尽pipe一些技巧可能会reflection)。