读AtomicBoolean源码之浅析

来源:互联网 发布:如何减腹部的赘肉 知乎 编辑:程序博客网 时间:2024/06/08 10:47

        AtomicBoolean位于java.util.concurrent.atomic包下,是java提供给的可以保证数据的原子性操作的一个类。下面通过源码来了解其实现原理。

        构造函数:

private volatile int value;/** * Creates a new {@code AtomicBoolean} with the given initial value. * * @param initialValue the initial value */public AtomicBoolean(boolean initialValue) {    value = initialValue ? 1 : 0;}/** * Creates a new {@code AtomicBoolean} with initial value {@code false}. */public AtomicBoolean() {}
      通过上述源码,我们了解到使用AtomicBoolean初始化时可以提供一个初始值。这个value有什么用呢?先看一下这个方法:

public final boolean compareAndSet(boolean expect, boolean update) {    return U.compareAndSwapInt(this, VALUE,                               (expect ? 1 : 0),                               (update ? 1 : 0));}
        这个方法是将比较和赋值操作作为一个原子操作,即在进行完比较和赋值操作之前,不会发生任何其他的操作。我们发现该方法的Value和我们初始化AtomicBoolean的并不是一个value啊,那这个Value是什么啊?看源码:

private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();private static final long VALUE;static {    try {        VALUE = U.objectFieldOffset            (AtomicBoolean.class.getDeclaredField("value"));    } catch (ReflectiveOperationException e) {        throw new Error(e);    }}
      虽然这个两个Value不是一个东西,但是在初始化完成之后,这两个的值确实相等的。这个全部大写的VALUE的意义何在呢?回头看一下compareAndSet方法,在进行比较和赋值操作的时候,用的都是这个VALUE,VALUE是value的一个副本,因为在使用过程中value的值是可以被修改的。

      至于比较和赋值操作的结果的返回值都是通过 sun.misc.Unsafe完成的。关于 sun.misc.Unsafe可以查阅:http://blog.csdn.net/dfdsggdgg/article/details/51543545

      最后再说明一下compareAndSet方法,这也是实现原子性的关键方法,源码注释如下:

/** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * * @param expect the expected value * @param update the new value * @return {@code true} if successful. False return indicates that * the actual value was not equal to the expected value.

      if(expect == VALUE){

     返回true,同时再将value的值更新为update的值;

     }else{

    返回false;

    }

     示例(来自网上):

    

  1. private static class BarWorker implements Runnable {  
  2.   
  3.   private static AtomicBoolean exists = new AtomicBoolean(false);  
  4.   
  5.   private String name;  
  6.   
  7.   public BarWorker(String name) {  
  8.    this.name = name;  
  9.   }  
  10.   
  11.   public void run() {  
  12.    if (exists.compareAndSet(falsetrue)) {  
  13.     System.out.println(name + " enter");  
  14.     try {  
  15.      System.out.println(name + " working");  
  16.      TimeUnit.SECONDS.sleep(2);  
  17.     } catch (InterruptedException e) {  
  18.      // do nothing  
  19.     }  
  20.     System.out.println(name + " leave");  
  21.     exists.set(false);  
  22.    }else{  
  23.     System.out.println(name + " give up");  
  24.    }  
  25.   }  
  26.   
  27.  }


0 0
原创粉丝点击