标签:基础 atomic efi 子类 bool swap 引用 border code
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标识是否被改过 | 
标签:基础 atomic efi 子类 bool swap 引用 border code
原文地址:https://www.cnblogs.com/zhangwanhua/p/10170782.html