compareAndSwap是个原子方法,原理是cas.就是说如果他是xx,那么就改为xxx.
这个是高效,而且是原子的,不用加锁.
也不用但是其他值改了而产生误操作,应为会先判断当前值,符合期望才去改变.
直接上代码吧
结果是:
fieldName:fieldOffset
intParam:12
longParam:16
strParam:24
strParam2:28
原始值是:3
true
改变之后的值是:10
false
true
compareAndSwapInt是通过反射根据字段偏移去修改对象的.
可以看到int是4个字节的偏移量,long是4个字节的偏移量,string是4个字节的偏移量
注意 Unsafe的对象不能直接new,要通过反射去获取.
这个是高效,而且是原子的,不用加锁.
也不用但是其他值改了而产生误操作,应为会先判断当前值,符合期望才去改变.
直接上代码吧
- package com.huangyunbin;
- import java.lang.reflect.Field;
- import sun.misc.Unsafe;
- public class UnsafeTest {
- private static Unsafe unsafe;
- static {
- try {
- //通过反射获取rt.jar下的Unsafe类
- Field field = Unsafe.class.getDeclaredField("theUnsafe");
- field.setAccessible(true);
- unsafe = (Unsafe) field.get(null);
- } catch (Exception e) {
- System.out.println("Get Unsafe instance occur error"+ e);
- }
- }
- public static void main(String[] args) throws Exception
- {
- Class clazz = Target.class;
- Field[] fields = clazz.getDeclaredFields();
- System.out.println("fieldName:fieldOffset");
- for (Field f : fields) {
- // 获取属性偏移量,可以通过这个偏移量给属性设置
- System.out.println(f.getName() + ":" + unsafe.objectFieldOffset(f));
- }
- Target target = new Target();
- Field intFiled = clazz.getDeclaredField("intParam") ;
- int a=(Integer)intFiled.get(target ) ;
- System.out.println("原始值是:"+a);
- //intParam的字段偏移是12 原始值是3 我们要改为10
- System.out.println(unsafe.compareAndSwapInt(target, 12, 3, 10));
- int b=(Integer)intFiled.get(target) ;
- System.out.println("改变之后的值是:"+b);
- //这个时候已经改为10了,所以会返回false
- System.out.println(unsafe.compareAndSwapInt(target, 12, 3, 10));
- System.out.println(unsafe.compareAndSwapObject(target, 24, null, "5"));
- }
- }
- class Target {
- int intParam=3;
- long longParam;
- String strParam;
- String strParam2;
- }
结果是:
fieldName:fieldOffset
intParam:12
longParam:16
strParam:24
strParam2:28
原始值是:3
true
改变之后的值是:10
false
true
compareAndSwapInt是通过反射根据字段偏移去修改对象的.
可以看到int是4个字节的偏移量,long是4个字节的偏移量,string是4个字节的偏移量
注意 Unsafe的对象不能直接new,要通过反射去获取.