线程阻塞非阻塞及原子量碰撞:http://my.oschina.net/bairrfhoinn/blog/167071
CAS:Compare and Swap, 翻译成比较并交换
- java.util.concurrent包完全建立在CAS之上的
- java.util.concurrent包中借助CAS实现了区别于synchronized同步锁的一种乐观锁
- Java中CAS主要由sun.misc.Unsafe实现,提供了硬件级别的原子操作
- Java无法直接访问到操作系统底层(如系统硬件等),因此Java使用native方法来扩展Java程序的功能,具体实现使用c++
Unsafe中关于CAS比较常用的方法:boolean sun.misc.Unsafe.compareAndSwapXXX(Object arg0, long arg1, int arg2, int arg3);
有4个操作数,1.内存值;2.属性偏移量;3.旧的预期值;4.要修改的新值。当且仅当旧的预期值和内存值相同时,将内存值修改为新值,否则什么都不做。
注:compareAndSwapXXX是根据字段偏移量去修改对象的值,其中int是4个字节的偏移量,long是4个字节的偏移量,String是4个字节的偏移量。偏移量与硬件机器有关。
Unsafe对象获取:Unsafe的对象不能直接new,要通过反射去获取。以下是获取方法:
private static Unsafe getUnsafeInstance() throws Exception {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
参考资料:http://www.importnew.com/7844.html
以简单的AtomicInteger为例:
public class AtomicInteger extends Number implements java.io.Serializable {
//...上略
private static final Unsafe unsafe = Unsafe.getUnsafe();
private volatile int value;
public AtomicInteger(int initialValue) {
value = initialValue;
}
public AtomicInteger() {}
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
public final int getAndSet(int newValue) {
for (;;) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
//...下略
}
- 使用volatile原语,保证线程间的数据是可见的(共享的)
- unsafe.compareAndSwapInt利用JNI来完成CPU指令的操作,同时借助JNI来完成Java的非阻塞算法(一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法)
参考资料:http://www.blogjava.net/xylz/archive/2010/07/04/325206.html
其他资料:
用AtomicStampedReference解决ABA问题:http://blog.hesey.net/2011/09/resolve-aba-by-atomicstampedreference.html
并发-原子操作的实现原理(CPU层面上的说明):http://www.searchsoa.com.cn/showcontent_69238.htm