zoukankan      html  css  js  c++  java
  • 并发(2) 原子类

      java并发包中提供了一些原子变量类,这些原子变量类提供的方法本身就是一个原子操作。

    例如

    public class CountingFactorizer implements Servlet{
    
              private final AtomicLong count = new AtomicLong(0);
    
              public void service(ServletRequest req,ServletResponse resp){
    
                        count.incrementAndGet();
    
              }
    
    }

      上例实现了对访问的计数,这是一个线程安全的类,因为它的计算是一个原子操作。java并发包中还提供了各种类型的原子变量类。

      那么原子变量类是如何实现计算的原子性的呢?

    public final int incrementAndGet() {
    
     for (;;) {
    
      int current = get();
    
      int next = current + 1;
    
       if (compareAndSet(current, next))
    
        return next;
    
      }
    
     }
    
    public final boolean compareAndSet(int expect, int update) {
    
         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    
    }

      上面的方法中,首现获取了当前的值,然后对当前值进行加1操作,然后通过unsafe的compareAndSet方法来设置改值。

      unsafe的compareAndSet方法做了什么呢?他首先会去比较当前值是不是预期的值,如果不是返回false,如果是设置新值并返回true。

      这种方式也叫做CAS,他不仅是原子类的底层实现方式,也是java显式锁的底层实现方式。就是在设置新值之前判断当前是否还是老值,如果是则设置新值,如果不是则重新计算新值后再尝试设置。当CAS实现原子性的基础是compareAndSet本身是一个原子操作,并且提供了内存可见性

    原子类

    原子类 说明
    AtomicBoolean boolean原子类 
    AtomicInteger int原子类
    AtomicLong long原子类
    AtomicReference 引用原子类
    AtomicIntegerArray int原子类数组
    AtomicLongArray long原子类数组
    AtomicReferenceArray 引用原子类数组
    AtomicIntegerFieldUpdater int原子类对象字段
    AtomicLongFieldUpdater long原子类对象字段
    AtomicReferenceFieldUpdater 引用原子类对象字段
    AtomicMarkableReference AtomicReference在使用时会出现aba问题,通过一个标识符号判断是否被改过
    AtomicStampedReference AtomicReference在使用时会出现aba问题,通过一个int标识是否被改过

     

     

  • 相关阅读:
    Leetcode 15 3Sum
    Leetcode 383 Ransom Note
    用i个点组成高度为不超过j的二叉树的数量。
    配对问题 小于10 1.3.5
    字符矩阵的旋转 镜面对称 1.2.2
    字符串统计 连续的某个字符的数量 1.1.4
    USACO twofive 没理解
    1002 All Roads Lead to Rome
    USACO 5.5.1 求矩形并的周长
    USACO 5.5.2 字符串的最小表示法
  • 原文地址:https://www.cnblogs.com/zhangwanhua/p/10170782.html
Copyright © 2011-2022 走看看