关闭

Netty的并发编程实践3:CAS指令和原子类

1279人阅读 评论(0) 收藏 举报
分类:

互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能的额外损耗,因此这种同步被称为阻塞同步,它属于一种悲观的并发策略,我们称之为悲观锁。随着硬件和操作系统指令集的发展和优化,产生了非阻塞同步,被称为乐观锁。简单地说,就是先进行操作,操作完成之后再判断操作是否成功,是否有并发问题,如果有则进行失败补偿,如果没有就算操作成功,这样就从根本上避免了同步锁的弊端。

目前,在Java中应用最广泛的非阻塞同步就是CAS,在IA64、X86指令集中通过cmpxchg指令完成CAS功能,在sparc-TSO中由case指令完成,在ARM和PowerPC架构下,需要使用一对Idrex/strex指令完成。

从JDK1.5以后,可以使用CAS操作,该操作由sun.misc.Unsafe类里的compareAndSwapInt()和compareAndSwapLong()等方法包装提供。通常情况下sun.misc.Unsafe类对于开发者是不可见的,因此,JDK提供了很多CAS包装类简化开发者的使用,如AtomicInteger。

下面,结合Netty的源码,我们对原子类的正确使用进行详细说明。

打开ChannelOutboundBuffer的代码,看看如何对发送的总字节数进行计数和更新操作,先看定义,如图21-9所示。


图21-9  原子类的应用

首先定义了一个volatile的变量,它可以保证某个线程对于totalPendingSize的修改可以被其他线程立即访问,但是,它无法保证多线程并发修改的安全性。紧接着又定义了一个AtomicIntegerFieldUpdater类型的变量WTOTAL_PENDING_SIZE_UPDATER,实现totalPendingSize的原子更新,也就是保证totalPendingSize的多线程修改并发安全性,我们重点看AtomicIntegerFieldUpdater的API说明,如图21-10所示。

从API的说明可以看出,它主要用于实现volatile修饰的int变量的原子更新操作,对于使用者,必须通过类似compareAndSet或者set或者与这些操作等价的原子操作来保证更新的原子性,否则会导致问题。

图21-10 AtomicIntegerFieldUpdater Java DOC说明

继续看代码,当执行write操作外发消息的时候,需要对外发的消息字节数进行统计汇总。由于调用write操作的既可以是I/O线程,也可以是业务的线程,还可能由业务线程池多个工作线程同时执行发送任务,因此,统计操作是多线程并发的,这也就是为什么要将计数器定义成volatile并使用原子更新类进行原子操作。下面看计数的代码,如图21-11所示。


图21-11  通过自旋对计数器进行更新

首先,我们发现计数操作并没有使用锁,而是利用CAS自旋操作,通过TOTAL_ PENDING_SIZE_UPDATER.compareAndSet(this,oldValue, newWriteBufferSize)来判断本次原子操作是否成功。如果成功则退出循环,代码继续执行;如果失败,说明在本次操作的过程中计数器已经被其他线程更新成功,需要进入循环,首先对oldValue进行更新,代码如下。

oldValue= totalPendingSize;

然后重新对更新值进行计算。

newWriteBufferSize= oldValue + size;

继续循环进行CAS操作,直到成功。它跟AtomicInteger的compareAndSet操作类似。

使用Java自带的Atomic原子类,可以避免同步锁带来的并发访问性能降低的问题,减少犯错的机会。因此,Netty中对于int、long、boolean等成员变量大量使用其原子类,减少了锁的应用,从而降低了频繁使用同步锁带来的性能下降。
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

java中的CAS和原子类的实现

CAS的全称为Compare-And-Swap,直译就是对比交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,经过调查发现,其实现方式是基于硬件平台的汇编指令,就是说CAS是靠硬件实现的,JVM只是封装了汇编调用,那些AtomicInteger类便是...
  • jijianshuai
  • jijianshuai
  • 2017-04-27 14:37
  • 603

CAS-比较&交换并发处理策略

这是一种可以称为基于冲突检测的乐观锁。这种模式下,已经没有所谓的锁概念了,每条线程都直接先去执行操作,计算完成后检测是否与其他线程存在共享数据竞争,如果没有则让此操作成功,如果存在共享数据竞争则可能不断地重新执行操作和检测,直到成功为止,可叫CAS自旋。 乐观锁的核心算法是CAS(Compar...
  • fyxxq
  • fyxxq
  • 2016-08-25 17:42
  • 1289

Netty的并发编程实践4:线程安全类的应用

在JDK1.5的发行版本中,Java平台新增了java.util.concurrent,这个包中提供了一系列的线程安全集合、容器和线程池,利用这些新的线程安全类可以极大地降低Java多线程编程的难度,提升开发效率。 新的并发编程包中的工具可以分为如下4类。 ◎   线程...
  • broadview2006
  • broadview2006
  • 2015-06-01 10:49
  • 1645

《JAVA并发编程实践》读书笔记(一)

《JAVA并发编程实践》读书笔记(一)2016年8月1日,“妮妲”冲击广东,全市放假1天。托“妮妲”的福,终于有空将近期的阅读整理一下。 最近利用业余时间重读了Brian Goetz的书,觉得受益匪浅。以前一知半解的概念和用法都在这次阅读中得到了答案。1.并发简史 并发随操作系统的发展而发展起来...
  • youngweiquan
  • youngweiquan
  • 2016-08-02 01:04
  • 632

Java 并发:原子类

概述: 关于JAVA原生的并发相关的,差不多都在java.util.concurent包下。里面的东西分成如下几大类: 1.原子类 2.锁相关的 3.多线程相关的 4.线程安全的集合,关于线程安全的集合,参考 http://blog.csdn.net/youyou1543724847/ar...
  • youyou1543724847
  • youyou1543724847
  • 2016-10-04 21:28
  • 2126

Netty的并发编程实践1:正确使用锁

很多刚接触多线程编程的开发者,虽然意识到了并发访问可变变量需要加锁,但是对于锁的范围、加锁的时机和锁的协同缺乏认识,往往会导致出现一些问题。下面笔者就结合Netty的代码来讲解下这方面的知识。 打开ForkJoinTask,我们学习一些多线程同步和协作方面的技巧。首先是当条件不满足时阻塞某个任务,...
  • broadview2006
  • broadview2006
  • 2015-05-27 09:35
  • 1263

《Java并发编程实践》笔记6——并发性调优

1.Amdahl定律: Amdahl(阿姆达尔)定律描述了在一个系统中,基于可并行化和串行化的组件各自所占的比重,程序通过获得额外的计算资源,理论上能够加速多少。若F是必须串行化执行的比重,那么在一个N处理器的机器中,通过Amdahl定律计算可以获得理论加速为: Speedup<=1/(F...
  • chjttony
  • chjttony
  • 2015-07-01 14:52
  • 3042

java原子类和CAS

本文转载自:http://blog.csdn.net/jijianshuai/article/details/70853776 什么是CAS     CAS的全称为Compare-And-Swap,直译就是对比交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原...
  • wwe4023
  • wwe4023
  • 2017-05-31 12:49
  • 142

并发编程--原子类AotmicInteger

前几篇博客中我们已经介绍了线程、volatile、synchronized和cas自旋相关的知识,接下来我介绍一下jdk提供的并发编程包java.util.concurrent中相关的实现类知识。 AtomicInteger简单来说就是一个能进行原子操作的Integer,这样在多线程操作下对Atom...
  • qq924862077
  • qq924862077
  • 2017-04-05 18:11
  • 537

Java并发基础(七)-原子类和并发集合类

灌水文1. 原子类 java.util.concurrent.atomic包下面提供了许多原子类,这些类是通过CAS实现的。关于CAS,大家可以google,详细学习下。 图中Atomic开头的是 jdk1.5开始提供的原子类。而其他则是在jdk1.8中新增加的。 Atomic开头的类中,大多都...
  • qq_21430549
  • qq_21430549
  • 2016-10-07 16:20
  • 738
    个人资料
    • 访问:3862795次
    • 积分:55917
    • 等级:
    • 排名:第58名
    • 原创:1461篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3782条
    博客专栏
    文章存档
    最新评论