• 测试技术
  • 博客
  • 视频
  • 开源
  • 论坛
  • 沙龙
  • 下载
  • 杂志
  • 招聘

字号: | 推荐给好友 上一篇 | 下一篇

Java 理论与实践 :关于非阻塞算法简介

发布: 2008-10-07 11:38 | 作者: 不详 | 来源: 领测软件测试网采编 | 查看: 22次 | 进入领测软件测试网论坛讨论

领测软件测试网 软件测试技术第一门户h/gDJ$P@f6k


UG`8uFQ@
w/WAaB x软件测试技术第一门户#G+bcu K
原子变量类之所以被称为原子的,是因为它们提供了对数字和对象引用的细粒度的原子更新,但是在作为非阻塞算法的基本构造块的意义上,它们也是原子的。非阻塞算法作为科研的主题,已经有 20 多年了,但是直到 Java 5.0 出现,在 Java 语言中才成为可能。
V(f"P*nbVt9O5p%z/~.z软件测试技术第一门户?0x ~ ~T2k
现代的处理器提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。(如果要做的只是递增计数器,那么 AtomicInteger 提供了进行递增的方法,但是这些方法基于 compareAndSet(),例如 NonblockingCounter.increment())。软件测试技术第一门户@T2Ni)\L*^ j

9`-e4x8b)X)ij非阻塞版本相对于基于锁的版本有几个性能优势。首先,它用硬件的原生形态代替 JVM 的锁定代码路径,从而在更细的粒度层次上(独立的内存位置)进行同步,失败的线程也可以立即重试,而不会被挂起后重新调度。更细的粒度降低了争用的机会,不用重新调度就能重试的能力也降低了争用的成本。即使有少量失败的 CAS 操作,这种方法仍然会比由于锁争用造成的重新调度快得多。
M Y\,x0RC?
[Fw hUMNNonblockingCounter 这个示例可能简单了些,但是它演示了所有非阻塞算法的一个基本特征 ?? 有些算法步骤的执行是要冒险的,因为知道如果 CAS 不成功可能不得不重做。非阻塞算法通常叫作乐观算法,因为它们继续操作的假设是不会有干扰。如果发现干扰,就会回退并重试。在计数器的示例中,冒险的步骤是递增 ?? 它检索旧值并在旧值上加一,希望在计算更新期间值不会变化。如果它的希望落空,就会再次检索值,并重做递增计算。
/t4H W.G^2~2?
B%Q&N Ehf5?b(m
KCZL.\ }y(gj非阻塞堆栈
h(y!cWn ?软件测试技术第一门户)n rM'raW
非阻塞算法稍微复杂一些的示例是清单 3 中的 ConcurrentStack。ConcurrentStack 中的 push() 和 pop() 操作在结构上与 NonblockingCounter 上相似,只是做的工作有些冒险,希望在 “提交” 工作的时候,底层假设没有失效。push() 方法观察当前最顶的节点,构建一个新节点放在堆栈上,然后,如果最顶端的节点在初始观察之后没有变化,那么就安装新节点。如果 CAS 失败,意味着另一个线程已经修改了堆栈,那么过程就会重新开始。软件测试技术第一门户[zo"vu
软件测试技术第一门户{GW.X-C,_
清单 3. 使用 Treiber 算法的非阻塞堆栈
"b3s,b