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. SQL 2008维护计划不执行的问题

    平台环境; 先是装了WINDOWS 2008,没有升级到AD,再安装了sql2008后再升级了AD. 现在SQL建了几个数据库备份计划,但都提示下面的信息: 日期  2010-4-15 9:36:00 ...

  2. HttpClientUtil 工具类

    /* * * * FileName: s.java * * Description:TODO(用一句话描述该文件做什么) * * Created: jiangzhanghong 2017年11月14日 ...

  3. ASP.NET中UrlEncode应该用Uri.EscapeDataString()(转)

    今天,茄子_2008反馈他博客中的“C++”标签失效.检查了一下代码,生成链接时用的是HttpUtility.UrlEncode(url),从链接地址获取标签时用的是HttpUtility.UrlDe ...

  4. avg(xxxxxx)什么时候能独自出现?

    avg(xxxxxx)是作为求一组数据的平均数,需要有这组数据的总数和个数,所以通常配合着group by来使用, 比如: SELECT ID, AVG(GRADE) AS 平均数 FROM TEST ...

  5. Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:generate (default-cli) on project : <properties> resource does not exist

    使用mybatis-generator自动生成mapper.dao等文件时,报错如下: org.apache.maven.lifecycle.LifecycleExecutionException: ...

  6. hdoj Max Sum Plus Plus(DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意:----最大M子段和问题给定由 n个整数(可能为负整数)组成的序列a1,a2,a3,……, ...

  7. Python3 input() 函数

    Python3 input() 函数  Python3 内置函数 Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型. 注意:在 Python3.x 中 ra ...

  8. day9:vcp考试

    Q161. An administrator wants to select a Host Power Management Policy for an ESXi 6.x host that will ...

  9. windows系统如何真正隐藏文件夹[转载]

    方法一(推荐)eg:现需隐藏e盘bak目录下的tools文件夹e:\bak\tools运行:cmd键入:attrib +s +a +h +r e:\bak\tools然后,你再进去看e盘bak目录下, ...

  10. 8-导弹拦截一(n^2 and nlogn)

    /*某国为了防御敌国的导弹袭击,研发出一套导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发拦截炮弹能够到达任意的高度,但是以后每一发拦截炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的多 ...