zoukankan      html  css  js  c++  java
  • 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型,
    还有一个特殊的AomicStampedReferrence,它不是AomicReferrence的子类,而是利用AomicReferrence实现的一个储存引用和Integer组的扩展类
     
    首先,所有原子操作都是依赖于sun.misc.Unsafe这个类,这个类底层是由C++实现的,利用指针来实现数据操作
     
    关于CAS
    一种无锁机制,比较并交换, 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无 论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可”
     
    好处:操作系统级别的支持,效率更高,无锁机制,降低线程的等待,实际上是把这个任务丢给了操作系统来做。
     
    这个理论是整个java.util.concurrent包的基础。
     
    关于sun.misc.Unsafe
     
    几个疑问
    1)四个基本类型的compareAndSet和weakCompareAndSet实现是一样的?
    2)AtomicLong的set方法非线程安全的,为啥?并非线程不全,而是对于Long的Updater,会有VM_SUPPORTS_LONG_CAS,如果JVM的long操作是原子化的,会采用无锁的CAS来更新,如果不支持就会使用带锁的方式来更新。
     
    AtomicXXXX四个数值类型
    1. value成员都是volatile
    2. 基本方法get/set
    3. compareAndSet
        weakCompareAndSet,
        lazySet: 使用Unsafe按照顺序更新参考Unsafe的C++实现)
        getAndSet:取当前值,使用当前值和准备更新的值做CAS
    4. 对于Long和Integer
    getAndIncrement/incrementAndGet
    getAndDecrement/decrementAndGet
    getAndAdd/addAndGet
    三组方法都和getAndSet,取当前值,加减之得到准备更新的值,再做CAS,/左右的区别在于返回的是当前值还是更新值。
     
    关于数组
    1. 没有Boolean的Array,可以用Integer代替,底层实现完全一致,毕竟AtomicBoolean底层就是用Integer实现
    2. 数组变量volatile没有意义,因此set/get就需要Unsafe来做了,方法构成与上面一致,但是多了一个index来指定操作数组中的哪一个元素。
     
    关于FieldUpdater
    1) 利用反射原理,实现对一个类的某个字段的原子化更新,该字段类型必须和Updater要求的一致,例如如果使用 AtomicIntegerFieldUpdater,字段必须是Integer类型,而且必须有volatile限定符。Updater的可以调用的方 法和数字类型完全一致,额外增加一个该类型的对象为参数,updater就会更新该对象的那个字段了。
    2) Updater本身为抽象类,但有一个私有化的实现,利用门面模式,在抽象类中使用静态方法创建实现
     
    AtomicMarkableReference/AtomicStampedReference
    前者ReferenceBooleanPair类型的AtomicReference,ReferenceBooleanPair表示一个对象和boolean标记的pair
    前者ReferenceIntegerPair类型的AtomicReference,ReferenceBooleanPair表示一个对象和Integer标记的pair
  • 相关阅读:
    file is universal (3 slices) but does not contain a(n) armv7s slice error for static libraries on iOS
    WebImageButton does not change images after being enabled in Javascript
    ajax OPTION
    编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    获取海洋天气预报
    C#线程系列教程(1):BeginInvoke和EndInvoke方法
    js控制只能输入数字和小数点
    Response.AddHeader(,)
    ManualResetEvent的理解
    Convert.ToInt32、int.Parse(Int32.Parse)、int.TryParse、(int) 区别
  • 原文地址:https://www.cnblogs.com/wanly3643/p/2829119.html
Copyright © 2011-2022 走看看