CAS
CAS (Compare And Swap) 比较和交换 cas(…,oldValue,newValue)方法必定会有两个参数, 若oldValue与内存中的值一致,就设置内存中的值为newValue,并返回true 若不致,放弃本次操作,反返回false CPU保证cas操作的原子性 cas操作需结合自旋,实现一直尝试,直到成功。即CAS方法本身不保证一定成功,但你可以选择再次尝试,直到成功为止。
封装Unsafe工具类,提供三个cas方法
package org. aidan;
import sun. misc. Unsafe;
import java. lang. reflect. Field;
public class UnsafeUtil {
private static Unsafe unsafe = null;
public static Unsafe getUnsafe ( ) {
if ( unsafe == null) {
synchronized ( UnsafeUtil. class ) {
if ( unsafe == null) {
try {
Field unsafeField = Unsafe. class . getDeclaredField ( "theUnsafe" ) ;
unsafeField. setAccessible ( true ) ;
Unsafe unsafe = ( Unsafe) unsafeField. get ( null) ;
return unsafe;
} catch ( NoSuchFieldException e) {
e. printStackTrace ( ) ;
} catch ( IllegalAccessException e) {
e. printStackTrace ( ) ;
}
}
}
}
return unsafe;
}
public static boolean casInt ( Object obj, String fileName, int oldValue, int newValue) {
try {
long offset = getOffset ( obj, fileName) ;
return getUnsafe ( ) . compareAndSwapInt ( obj, offset, oldValue, newValue) ;
} catch ( NoSuchFieldException e) {
e. printStackTrace ( ) ;
}
return false ;
}
public static boolean casLong ( Object obj, String fileName, long oldValue, long newValue) {
try {
long offset = getOffset ( obj, fileName) ;
return getUnsafe ( ) . compareAndSwapLong ( obj, offset, oldValue, newValue) ;
} catch ( NoSuchFieldException e) {
e. printStackTrace ( ) ;
}
return false ;
}
public static boolean casObject ( Object obj, String fileName, Object oldValue, Object newValue) {
try {
long offset = getOffset ( obj, fileName) ;
return getUnsafe ( ) . compareAndSwapObject ( obj, offset, oldValue, newValue) ;
} catch ( NoSuchFieldException e) {
e. printStackTrace ( ) ;
}
return false ;
}
private static long getOffset ( Object obj, String fileName) throws NoSuchFieldException {
long offset;
Field field;
if ( obj instanceof Class ) {
Class clazz = ( Class) obj;
field = clazz. getDeclaredField ( fileName) ;
offset = getUnsafe ( ) . staticFieldOffset ( field) ;
} else {
field = obj. getClass ( ) . getDeclaredField ( fileName) ;
offset = getUnsafe ( ) . objectFieldOffset ( field) ;
}
return offset;
}
}