Spring源码学习-AtomicBoolean

Spring源码学习-AtomicBoolean

AtomicBoolean volatile


在阅读这个类的时候发现了几个值得注意的地方。

volatile

private volatile int value;
  • 编译器优化:

使用了volatile的关键字。意在声明这个所有对这个变量操作,编译器就不会对其进行优化。 举例:
i=1;
i=2;
i=3;
编译器为了优化执行效率,会自动的默认视为一条指令,即i=3(自动跳过前面两条无用的指令);
但是加了volatile关键字,则每条指令都会得到执行,i这个变量前后被赋值3次。

注:单线程的时候,不会出现问题,但是多线程执行的时候,就会出现大问题了。

  • 读值位置

cpu的处理速度跟内存的频率是相差很大的,为了减小这种差距,所以有了高频率的cpu缓存--寄存器(在cpu中)。cpu在读取数据的时候,先从内存中copy一份到寄存器中,然后从寄存器中读取。这就存在一个同步的问题。valatile的使用告诉了cpu,每次都从内存中读取值。


objectFieldOffset

 valueOffset = unsafe.objectFieldOffset
                (AtomicBoolean.class.getDeclaredField("value"));

这个方法是使用的native方法,public native long objectFieldOffset(Field var1); 这个方法直接操作内存,告知相对地址的位置。感觉类似c++的指针,但是这个是相对位置而已,还需要再经过映射才能到实际地址。


compareAndSwapInt

3、unsafe.compareAndSwapInt(this, valueOffset, e, u)

这个方法是原子性的操作,也是调用native的方法,进行比较和交换。
在openJDK中找到了Unsafe的实现,调用的是C的封装的类。

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))  
  UnsafeWrapper("Unsafe_CompareAndSwapInt");  
  oop p = JNIHandles::resolve(obj);  
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);  
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;  
UNSAFE_END  

inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {  
  // alternative for InterlockedCompareExchange  
  int mp = os::is_MP();  
  __asm {  
    mov edx, dest  
    mov ecx, exchange_value  
    mov eax, compare_value  
    LOCK_IF_MP(mp)  
    cmpxchg dword ptr [edx], ecx  
  }  
}  

到后面基本是汇编程序了,实际上这里也是使用了lock(LOCK_IF_MP)来保证。

你可能感兴趣的:(Spring源码学习-AtomicBoolean)