七、真正的技术——CAS操作原理、实现、底层源码

11、CAS原理与实现:

    1、定义:
	比较和交换(Conmpare And Swap,简称CAS)是用于实现多线程同步的原子指令。
	JAVA中的CAS操作都是通过sun包下Unsafe类实现,而Unsafe类中的方法都是native方,
	native方法的实现位于unsafe.cpp
	
	源码流程如下:
	    java中方法(以AtomicInteger为例):
		public final boolean compareAndSet(int expect, int update) {
		    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
		}
		//对象o中offset偏移位置的值等于期望值(expected),
		//就将该offset处的值更新为x,当更新成功时,返回true,
		//native标记的方法在C++底层实现
		public final native boolean compareAndSwapInt(Object o, long offset, 
		    int expected, int x);
		
		unsafe.cpp中C++方法(compareAndSwapInt实现):
			//定义
			UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, 
			    jobject unsafe, jobject obj, jlong offset, jint e, jint x))
			  UnsafeWrapper("Unsafe_CompareAndSwapInt");
			  //判断obj是否为空,返回obj指针的值
			  oop p = JNIHandles::resolve(obj);
			  //用p的地址加上offset得到具体内存地址
			  jint* addr = (jint *) index_oop_from_field_offset_long
			    (p, offset);
			  //通过Atomic::cmpxchg实现比较替换,其中参数x是即将更新的值,
			    参数e是原内存的值
			  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
			UNSAFE_END

			//内联汇编
			inline jint Atomic::cmpxchg (jint exchange_value, 
			    volatile jint* dest, jint compare_value) {
			    int mp = os::isMP(); //判断是否是多处理器
			    //volatile表示禁止编译器优化
			    __asm__ volatile (
			    //根据当前系统是否为多核处理器决定是否为cmpxchg指令
			      添加lock前缀
			    LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
                            : "=a" (exchange_value)
                            : "r" (exchange_value), "a" (compare_value), "r" (dest), 
                                "r" (mp)
                            : "cc", "memory");
			    }
	总结:
	    CAS操作实现:
	        用预期值A1和内存值A2做对比,如果A1等于A2,则内存值修改成B并返回true,
	        否则不操作并返回false。
	
	缺点:
	    ABA问题:多线程时,其余线程修改内存值之后又还原为初始值,
	    当前线程比较值时,值一样则操作成功。
	解决办法:
	    java并发包中提供了一个带有标记的原子引用类AtomicStampedReference,
	    通过控制变量值的版本来保证CAS的正确性。
	    
	    AtomicStampedReference以一个int值作为版本号,
	    每次更改前先取到这个int值的版本号,
	    等到修改的时候,比较当前版本号与当前线程持有的版本号是否一致,
	    如果一致,则进行修改,并将版本号+1。
复制代码

你可能感兴趣的:(七、真正的技术——CAS操作原理、实现、底层源码)