Heinz Kabutz 在上周举办了一次成功 JCrete研讨会,我在会上参加了对一种新的 StampedLock(于JSR166中 引入) 进行的评审。StampedLock (邮戳锁) 旨在解决系统中共享资源的争用问题。在一个系统中,如果多个需要读写某一共享状态的程序并发访问这个共享对象时,争用问题就产生了。在设计 上,StampedLock 试图通过一种“乐观读取”的方式来减小系统开销,从而提供比 ReentrantReadWriteLock(重入读写锁) 更好的性能。

在评审过程中,我产生了许多想法:首先,这是我第一次评审Java 中最新锁机制的实现。其次,尽管 StampedLock 看起来是一个对 JDK 不错的补充,但是它似乎忽略了一个事实——无锁算法通常在多读取程序访问共享资源时能提供更好的性能。

测试用例

为了比较不同的实现,我首先需要一个 API 调用作为测试用例。这个 API 调用不能在某些算法或条件下表现出特别的性质,比如这个调用不应产生垃圾对象,同时调用的方法可以具有原子性。据此我构造了一个简单的测试用例——构建一 个宇宙飞船,这个飞船可以在二维的空间上根据其当前的坐标进行移动,其坐标(横纵坐标)可以使用原子操作进行读取。这样,我们在一次移动操作时,至少有两 个需要被读取或修改的数据。这种条件足以让我们系统的并发性能进行测试。

1
2
3
4
5
public interface Spaceship
{
    int readPosition(final int[] coordinates);
    int move(final int xDelta, final int yDelta);
}

如果不使用不可修改(immutable)的坐标对象,上面的接口定义可以更清晰一些。但是我希望保留它,这样该接口不会产生无效对象。同时,这样做还可以更明确地表明该接口会修改多个内部变量。此外,这个接口还可以很容易地在保持原子性的前提下扩展到三维空间。
我实现了多种不同的并发算法来操作飞船,并用一个测试程序来执行不同的实现。代码和所有的执行结果可以这里找到。

测试程序将按照超多态分发(megamorphic dispatch)模式依次运行不同的实现。这是为了防止 JVM 在运行时优化并发调用的接口,例如用函数实现替换函数接口、弱化锁机制或者展开循环。这些优化会影响我们的测评结果。

每种并发算法的实现都在四种不同的线程环境下进行了测试,并表现出不同的特征:

  • 单读取、单写入
  • 双读取、单写入
  • 三读取、单写入
  • 双读取、双写入

所有的测试均在下面环境中进行,Java 1.7.0_25 64-位、Linux 3.6.30 、双核 2.2GHz Ivy Bridge
i7-3632QM
CPU。每一种实现的测试均重复5次以确保结果的稳定性,具体的吞吐量是以5秒为周期进行测量。下面的结果显示了综合5次测试结果后的每秒平均吞吐量。为
了贴近通常的 Java
部署环境,测试中没有配置线程绑定(由指定核运行)或对CPU的分工进行划分,因为对CPU的使用的划分在极大程度上会降低实现间的差异。

注意: 使用其他CPU和操作系统可能导致迥异的测试结果。

图1 图2 图3 图4

上图中的原始数据可以在这里找到。

分析

真正让我惊讶的是 ReentrantReadWriteLock 在测试所表现出的性能。对于
ReentrantReadWriteLock,最适合的应用场景应该是当系统中存在有大量的读取需求以及极少的写入需求时(如上图2、图3所示)。下面
是这次测试的主要收获:

  1. StampedLock 是对现有锁机制实现的一个很好补充,当更多的读取者参与竞争时尤其如此。
  2. StampedLock 有着复杂的API,可能会引起对其方法或者锁定动作的误用。
  3. 在解决两个线程间的竞争问题时,synchronized 是一个不错的通用的锁机制。
  4. 之前提到的,当线程数增加时ReentrantLock 可以作为一个不错的通用锁机制解决竞争问题。
  5. 在考虑是否选择使用 ReentrantReadWriteLock 时,首先需要进行仔细并恰当的测试来衡量其性能。好比所有重要的决策,都应该根据真实数据来进行评估和决策。
  6. 无锁实现在提高吞吐量方面的能力远超有锁的同步算法。

总结

无锁技术在有锁同步算法中的应用带来了可喜的结果。在读取对象时采用乐观策略无疑是对无锁算法中的技术的有效利用。

在我教授无锁算法以及实际的开发经历中,无锁技术不仅仅提供了更高的吞吐量——如测试中验证的那样,同时在响应延迟上的抖动上也要较有锁算法小很多。

Results

Figure 1.
Figure 2.
Figure 3.
Figure 4.

转载 http://www.importnew.com/7774.html

加锁并发算法 vs 无锁并发算法的更多相关文章

  1. 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现

    [实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...

  2. (转载)java高并发:CAS无锁原理及广泛应用

    java高并发:CAS无锁原理及广泛应用   版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...

  3. lock free(无锁并发)是什么

    一.非阻塞同步(Non-blocking Synchronization) 1. 无锁编程 / lock-free / 非阻塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线 ...

  4. Lock Free (无锁并发)

    CAS( compare and swap) 原子操作,保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入.而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致 ...

  5. 无锁并发框架Disruptor学习入门

    刚刚听说disruptor,大概理一下,只为方便自己理解,文末是一些自己认为比较好的博文,如果有需要的同学可以参考. 本文目标:快速了解Disruptor是什么,主要概念,怎么用 1.Disrupto ...

  6. 基于无锁的C#并发队列实现(转载)

    最近开始学习无锁编程,和传统的基于Lock的算法相比,无锁编程具有其独特的优点,Angel Lucifer的关于无锁编程一文对此有详细的描述. 无锁编程的目标是在不使用Lock的前提下保证并发过程中共 ...

  7. 基于无锁的C#并发队列实现

    最近开始学习无锁编程,和传统的基于Lock的算法相比,无锁编程具有其独特的优点,Angel Lucifer的关于无锁编程一文对此有详细的描述. 无锁编程的目标是在不使用Lock的前提下保证并发过程中共 ...

  8. 【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

  9. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

随机推荐

  1. PPT汇报 评审表

    评审表 团队编号 团队名称 团队项目名称 格式评审 内容评审 PPT评审 演讲评审 优点 存在问题(至少提3点) 建议 01 牛肉面不要牛肉不要面 02 正义联盟 我是一个图书小平台 03 什么队 & ...

  2. 求数组中的逆序对的数量----剑指offer36题

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数: 如数组{7,5,6,4},逆序对总共有5对,{7,5},{7,6},{7, ...

  3. get与load方法

    get()与load()的共同点:根据id加载对象get()与load()的区别:get():若加载的对象不存在,则返回nullload():若加载的对象不存在,则抛出异常

  4. struts2 参数注入 方法拦截器

    web.xml: <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=" ...

  5. 给vim编辑器自动添加行号

    1.只改变当前用户的vim 在~目录下  vim .vimrc添加一行 set number 即可(普通用户权限即可) 2. 改变所有用户的vim 打开文件 /etc/vimrc 添加一行 set n ...

  6. -moz 火狐 -msIE -webkit[chrome safari]

    -moz代表firefox浏览器私有属性 -ms代表IE浏览器私有属性 -webkit代表chrome.safari私有属性

  7. T分布(T-Distribution)

    1.What is the T Distribution? T分布(也叫Student 's T分布)是一组与正态分布曲线几乎相同的分布,只是更短更胖一点.当有小样本时,使用t分布而不是正态分布.样本 ...

  8. android笔记 : Content provider内容提供器

    内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能. 内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内 ...

  9. Python vars() 函数

    Python vars() 函数  Python 内置函数 描述 vars() 函数返回对象object的属性和属性值的字典对象. 语法 vars() 函数语法: vars([object]) 参数 ...

  10. android 混淆文件proguard.cfg详解 (转载)

    -injars  androidtest.jar[jar包所在地址] -outjars  out[输出地址] -libraryjars    'D:\android-sdk-windows\platf ...