zoukankan      html  css  js  c++  java
  • AtomicReference和AtomicStampedReference

    AtomicReference类提供了一个可以原子读写的对象引用变量。 原子意味着尝试更改相同AtomicReference的多个线程(例如,使用比较和交换操作)不会使AtomicReference最终达到不一致的状态。 AtomicReference甚至有一个先进的compareAndSet()方法,它可以将引用与预期值(引用)进行比较,如果它们相等,则在AtomicReference对象内设置一个新的引用。

    一、AtomicReference

    通过volatile和Unsafe提供的CAS函数实现原子操作。 自旋+CAS的无锁操作保证共享变量的线程安全

    1. value是volatile类型,这保证了:当某线程修改value的值时,其他线程看到的value的值都是最新的值,即修改之后的volatile的值
    2. 通过CAS设置value。这保证了:某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作时原子性的,即线程在操作vu略时不会被中断。

    但是CAS操作可能存在ABA问题。AtomicStampedReference的出现就是为了解决这问题

    备注:ABA问题:原始值为A,某个线程修改为B,另一个线程又修改为A,当第三个线程访问时,获取的值依然是A,认为该值没有被修改过。

    注意:如下代码是线程不安全的

    //先获取原始值
    Integer oldValue = atomicReference.get();
    //根据原始值比较进行修改
    atomicReference.compareAndSet(oldValue,oldValue+1);

    若要保证线程安全,需要加锁(Lock或者synchronized)

    Lock lock = new ReentrantLock();
    ...
     lock.lock();
     Integer oldValue = atomicReference.get();
     atomicReference.compareAndSet(oldValue,oldValue+1);
    lock.unlock();

    也就是说对于AtomicXX类,单个方法是原子性的,但是同时调用多个方法则不是原子性的,需要加锁实现线程安全。

    二、AtomicStampedReference

    AtomicStampedReference它内部不仅维护了对象值,还维护了一个时间戳(我这里把它称为时间戳,实际上它可以是任何一个整数,它使用整数来表示状态值)。当AtomicStampedReference对应的数值被修改时,除了更新数据本身外,还必须要更新时间戳。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值,写入才会成功。因此,即使对象值被反复读写,写回原值,只要时间戳发生变化,就能防止不恰当的写入。

    举个栗子

    AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference(0,1);
      lock.lock();
     Integer oldValue = atomicStampedReference.getReference();//0
     int stamp = atomicStampedReference.getStamp();//1
     atomicStampedReference.compareAndSet(oldValue,oldValue+1, stamp,stamp+1);
     lock.unlock();
     System.out.println(atomicStampedReference.getReference());//1
     System.out.println(atomicStampedReference.getStamp());//2
  • 相关阅读:
    Linux配置NTP服务器,时间同步
    个人博客:有态度的HBase/Spark/BigData
    solr 6.2.1环境搭建
    大牛博客!Spark / Hadoop / Kafka / HBase / Storm
    hive 数据导出三种方式
    hive 分区表
    hive 创建orc表
    Tomcat中JVM内存溢出及合理配置及maxThreads如何配置(转)
    oracle 日期时间函数
    02: linux命令bak
  • 原文地址:https://www.cnblogs.com/cq-yangzhou/p/12050192.html
Copyright © 2011-2022 走看看