• 并发(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标识是否被改过

     

     

  • 相关阅读:
    API Hook完全手册
    ASP.NET页面刷新的实现方法
    ASP.NET验证码
    ASP.NET优化性能的方法
    Asp.net中Server.Transfer,Server.Execute和Response.Redirect的区别
    FireFox新标签页打开搜索和书签
    win10里如何在中文输入法里添加美式键盘
    Sublime Text 3中文乱码问题解决
    Win2008 r2 IIS7.5出现“FastCGI进程最近常常失败。请过一会再尝试此请求”的解决方法
    Sublime Text 3中设置不记住上次打开的文件
  • 原文地址:https://www.cnblogs.com/zhangwanhua/p/10170782.html
Copyright © 2020-2023  润新知