非阻塞算法(non-blocking algorithms)定义
 
     所谓非阻塞算法是相对于锁机制而言的,是指:一个线程的失败或挂起不应该引起另一个线程的失败或挂起的一种算法。一般是利用硬件层面支持的原子化操作指令来取代锁的,比如CAS(compare and swap),从而保证共享数据在并发访问下的数据一致性。
 
由AtomicInteger的线程安全机制说起
 
AtomicInteger内部是如何保证线程同步的呢?我们先看AtomicInteger内部的一个典型的方法:
     public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
   }
     public final boolean compareAndSet (int expect, int update) {
       return unsafe.compareAndSwapInt(thisvalueOffset, expect, update);
   }
 
解释:compareAndSet方法内部是调用Java本地方法compareAndSwapInt来实现的,而compareAndSwapInt方法内部又是借助C来调用CPU的底层指令来保证在硬件层面上实现原子操作的。在intel处理器中,CAS是通过调用cmpxchg指令完成的。这就是我们常说的CAS操作(compare and swap)。CAS操作很容易理解,一般来说有三个值:内存值V,期望值A,更新值B,如果内存值V和期望值A相等,那么就用更新值B替换内存值,否则什么都不做。想象一下,假设AtomicInteger当前的value值为1,某个线程A正在执行上述的getAndSet方法,当执行到compareAndSet方法的时候,被另一个线程B抢占了,线程B成功将内存值更新为2,然后轮到线程A来继续执行上述还没有执行完的比较并更新操作,由于线程A上次获得到的current值是1,然后开始执行compareAndSet方法(最后交由CPU的原子执行来执行的),comareAndSet方法发现当前内存值V=2,而期望值A=1(current变量值),所以就不会产生值交换,然后继续下一次重试,在没有别的线程抢占的情况下,下一个循环(在并发很高的情况下可能经过更多次的循环)线程A就能够设置成功,如果线程A是在还没有运行int current = get()这一行操作时被抢占了,那么线程B运行完毕后,线程A获得的将是线程B修改后的值然后进行CAS操作可能就一次成功(在没有其他线程抢占的情况下)。因此,CAS Try-Loop操作能够很好的提供线程同步机制,我们又将此实现过程称之为线程同步的无阻塞算法,又叫”CAS循环”,”lock-free“或”wait-free“算法。
 
非阻塞算法的优点
 
  在java5.0版本时,我们只能通过synchronized来实现线程的同步,synchronized是一种独占锁,独占锁是一种悲观锁,当一个线程访问共享资源的时候,其他线程必须处在阻塞状态,只有在拥有锁的线程释放锁以后才能被其他线程锁竞争,JVM 实现阻塞的方式通常是挂起阻塞的线程,过一会儿再重新调度它。由此造成的上下文切换相对于锁保护的少数几条指令来说,会造成相当大的延迟,这将引起性能问题,所以我们称这种锁为重量级锁。所谓乐观锁就是指:对竞争资源不用加锁,而是假设没有冲突去完成某项操作,如果因为冲突失败就不断重试,直到成功为止。上面所说的循环CAS操作就是上述所说的乐观锁。
  1. 利用硬件的原生支持代替JVM对代码路径的锁定,从而提供更细粒度(独立的内存地址)的同步。
  2. 失败的线程可以立即重试而不用被挂起,降低了争用成本,即使有少量失败的CAS操作,也依然锁争用造成的重新调度快的多
  3. 争用CAS提供更短的延迟(因为争用CAS比争用锁会更快),提供更好的吞吐率。
  4. 对生存问题(死锁和线程优先级反转)提供更好的防御
在轻度到中度的争用情况下阻塞算法的性能会超越阻塞算法,因为 CAS 的多数时间都在第一次尝试时就成功,而发生争用时的开销也不涉及线程挂起和上下文切换,只多了几个循环迭代。没有争用的 CAS 要比没有争用的锁便宜得多(这句话肯定是真的,因为没有争用的锁涉及 CAS 加上额外的处理),而争用的 CAS 比争用的锁获取涉及更短的延迟。在高度争用的情况下(即有多个线程不断争用一个内存位置的时候),基于锁的算法开始提供比非阻塞算法更好的吞吐率,因为当线程阻塞时,它就会停止争用,耐心地等候轮到自己,从而避免了进一步争用。但是,这么高的争用程度并不常见,因为多数时候,线程会把线程本地的计算与争用共享数据的操作分开,从而给其他线程使用共享数据的机会。
 
参考:

基于CAS操作的非阻塞算法的更多相关文章

  1. Java锁与非阻塞算法的性能比较与分析+原子变量类的应用

    15.原子变量与非阻塞同步机制 在java.util.concurrent包中的许多类,比如Semaphore和ConcurrentLinkedQueue,都提供了比使用Synchronized更好的 ...

  2. 《java并发编程实战》读书笔记12--原子变量,非阻塞算法,CAS

    第15章 原子变量与非阻塞同步机制 近年来,在并发算法领域的大多数研究都侧重于非阻塞算法,这种算法用底层的原子机器指令(例如比较并交换指令)代替锁老确保数据在并发访问中的一致性. 15.1 锁的劣势 ...

  3. Java 理论与实践: 非阻塞算法简介——看吧,没有锁定!(转载)

    简介: Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能.非阻塞算法属于并发算法,它们可以安全地派生它们的线程, ...

  4. Java 理论与实践: 非阻塞算法简介--转载

    在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是synchronized 关键字(也称为内在锁),它强制实行互斥,确保 ...

  5. java并发之非阻塞算法介绍

    在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在算法中如果一个线程的挂起没有导致其它的线程挂起,我们就说这个算法是非阻塞的. 为了更好的理解阻塞算 ...

  6. 29、Java并发性和多线程-非阻塞算法

    以下内容转自http://ifeve.com/non-blocking-algorithms/: 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在 ...

  7. Java 理论与实践-非阻塞算法简介

    在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情.Java 语言中主要的同步手段就是 synchronized 关键字(也称为内在锁),它强制实行互斥,确 ...

  8. 非阻塞算法(Lock-Free)的实现

    目录 非阻塞的栈 非阻塞的链表 非阻塞算法(Lock-Free)的实现 上篇文章我们讲到了使用锁会带来的各种缺点,本文将会讲解如何使用非阻塞算法.非阻塞算法一般会使用CAS来协调线程的操作. 虽然非阻 ...

  9. 《Java并发编程实战》笔记-非阻塞算法

    如果在某种算法中,一个线程的失败或挂起不会导致其他线程也失败和挂起,那么这种算法就被称为非阻塞算法.如果在算法的每个步骤中都存在某个线程能够执行下去,那么这种算法也被称为无锁(Lock-Free)算法 ...

随机推荐

  1. 2018.07.31 bzoj4569: [Scoi2016]萌萌哒(并查集+倍增)

    传送门 对于每个限制,使用倍增的二进制拆分思想,用并查集数组fa[i][j]" role="presentation" style="position: rel ...

  2. C# winIO32位,64位的使用(运行时要用管理员身份)

    下载地址: http://www.internals.com/utilities/WinIo.zip 一个按键的消息产生流程如下: 1)硬件中断/硬件端口数据 WinIO能模拟,或者修改IDT是在这一 ...

  3. 日期 时间选择器(DatePicker和TimePicker)实现用户选择

    日期和时间 作者的设计TimePicker时,大小分布不合理,我调整宽度为match-parent高度为wrap-parent就可以了. public class MainActivity exten ...

  4. HDU 5957 Query on a graph (拓扑 + bfs序 + 树剖 + 线段树)

    题意:一个图有n个点,n条边,定义D(u,v)为u到v的距离,S(u,k)为所有D(u,v)<=k的节点v的集合 有m次询问(0<=k<=2): 1 u k d:将集合S(u,k)的 ...

  5. UVa 12034 Race (递推+组合数学)

    题意:A,B两个人比赛,名次有三种情况(并列第一,AB,BA).输入n,求n个人比赛时最后名次的可能数. 析:本来以为是数学题,排列组合,后来怎么想也不对.原来这是一个递推... 设n个人时答案为f( ...

  6. TurtleBot教程

    TurtleBot TurtleBot combines popular off-the-shelf robot components like the iRobot Create, Yujin Ro ...

  7. hdu2571 命运 2016-09-11 16:54 53人阅读 评论(0) 收藏

    命运 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  8. 老刘 Yii2 源码学习笔记之 Module 类

    关系类图 从上图可以看出 Application 类继承了 Module,在框架中的是非常重要角色. 加载配置 public function setModules($modules) { forea ...

  9. 大猪蹄子队 Scrum meeting 合集

    大猪蹄子队 Scrum meeting 合集 18-10-29 第一天 http://note.youdao.com/noteshare?id=79ce5a89f85995ef68deae14e538 ...

  10. DBCC--CHECKDB--结果收集

    --由宋沄剑提供 CREATE TABLE [dbo].[dbcc_history]( [Error] [int] NULL, [Level] [int] NULL, [State] [int] NU ...