sun.misc.Unsafe

package com.rt.sun.misc.utils;

public class Person {

    private static String staticStringField;

    private String stringField;

    private int intField;

    private long longField;

    public static String getStaticStringField() {
        return staticStringField;
    }

    public static void setStaticStringField(String staticStringField) {
        Person.staticStringField = staticStringField;
    }

    public String getStringField() {
        return stringField;
    }

    public void setStringField(String stringField) {
        this.stringField = stringField;
    }

    public int getIntField() {
        return intField;
    }

    public void setIntField(int intField) {
        this.intField = intField;
    }

    public long getLongField() {
        return longField;
    }

    public void setLongField(long longField) {
        this.longField = longField;
    }

    @Override
    public String toString() {
        return "Person{" +
                "staticStringField='" + staticStringField + "'" +
                "stringField='" + stringField + "'" +
                ", intField=" + intField +
                ", longField=" + longField +
                '}';
    }
}

 

package com.rt.sun.misc.utils;

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class UnsafeUtil {

    private static final Unsafe unsafe;

    static {
        unsafe = getUnsafeInstance();
    }


    public static void main(String[] args) {

        long staticStringFieldOffset = getStaticFieldOffset(Person.class, "staticStringField");
        System.out.println("类变量[staticStringField]相对于类内存地址的偏移量:"+staticStringFieldOffset);
        long stringFieldOffset = getFieldOffset(Person.class, "stringField");
        System.out.println("成员变量[stringField]相对于实例对象内存地址的偏移量:"+stringFieldOffset);
        long intFieldOffset =  getFieldOffset(Person.class, "intField");
        System.out.println("成员变量[intField]相对于实例对象内存地址的偏移量:"+intFieldOffset);
        long longFieldOffset =  getFieldOffset(Person.class, "longField");
        System.out.println("成员变量[longField]相对于实例对象内存地址的偏移量:"+longFieldOffset);

        Person person = new Person();
        System.out.println("初始:"+person.toString());
        // Person.staticStringFieldOffset="staticStringField-value";
        putObject(Person.class, staticStringFieldOffset, "staticStringField-value");
        // person.stringFieldOffset="stringField-value";
        putObject(person, stringFieldOffset, "stringField-value");
        // person.intFieldOffset=1;
        putInt(person, intFieldOffset, 1);
        // person.longFieldOffset=1L;
        putLong(person, longFieldOffset, 1L);
        System.out.println("修改之后:"+person.toString());

        // [CAS]Person.staticStringFieldOffset="cas-staticStringField-value";
        compareAndSwapObject(person, staticStringFieldOffset, person.getStringField(), "cas-staticStringField-value");
        // [CAS]person.stringFieldOffset="cas-stringField-value";
        compareAndSwapObject(person, stringFieldOffset, person.getStringField(), "cas-stringField-value");
        // [CAS]person.intFieldOffset=2;
        compareAndSwapInt(person, intFieldOffset, person.getIntField(), 2);
        // [CAS]person.longFieldOffset=2L;
        compareAndSwapLong(person, longFieldOffset, person.getLongField(), 2L);
        System.out.println("CAS修改之后:"+person.toString());
    }


    /**
     * 通过反射创建Unsafe实例对象
     * @return
     */
    public static Unsafe getUnsafeInstance() {
        Unsafe unsafe = null;
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        }
        return unsafe;
    }

    /**
     * 获取某类的静态变量相对于类内存地址的偏移量
     * @param cls           类
     * @param fieldName     类的静态变量名
     * @return              静态变量相对于类内存地址的偏移量
     */
    public static long getStaticFieldOffset(Class<?> cls, String fieldName) {
        long offset = 0L;
        try {
            offset = unsafe.staticFieldOffset(cls.getDeclaredField(fieldName));
        } catch (NoSuchFieldException e0) {
            e0.printStackTrace();
        }
        return offset;
    }

    /**
     * 获取类的成员变量相对于实例对象内存地址的偏移量
     * @param cls           类
     * @param fieldName     实例对象中的成员变量名
     * @return              成员变量相对于实例对象内存地址的偏移量
     */
    public static long getFieldOffset(Class<?> cls, String fieldName) {
        long offset = 0L;
        try {
            offset = unsafe.objectFieldOffset(cls.getDeclaredField(fieldName));
        } catch (NoSuchFieldException e0) {
            e0.printStackTrace();
        }
        return offset;
    }

    /**
     * 修改类的静态变量值
     * @param cls               类
     * @param fieldOffset       类变量相对于类内存地址的偏移量
     * @param fieldValue        静态变量的新值
     */
    public static void putObject(Class<?> cls, long fieldOffset, String fieldValue) {
        unsafe.putObject(cls, fieldOffset, fieldValue);
    }

    /**
     * 修改对象的成员变量值
     * @param person            对象实例
     * @param fieldOffset       成员变量相对于实例对象内存地址的偏移量
     * @param fieldValue        成员变量的新值
     */
    public static void putObject(Person person, long fieldOffset, String fieldValue) {
        unsafe.putObject(person, fieldOffset, fieldValue);
    }

    /**
     * 修改对象的成员变量值
     * @param person            对象实例
     * @param fieldOffset       成员变量相对于实例对象内存地址的偏移量
     * @param fieldValue        成员变量的新值
     */
    public static void putInt(Person person, long fieldOffset, int fieldValue) {
        unsafe.putInt(person, fieldOffset, fieldValue);
    }

    /**
     * 修改对象的成员变量值
     * @param person            对象实例
     * @param fieldOffset       成员变量相对于实例对象内存地址的偏移量
     * @param fieldValue        成员变量的新值
     */
    public static void putLong(Person person, long fieldOffset, long fieldValue) {
        unsafe.putLong(person, fieldOffset, fieldValue);
    }

    /**
     * CAS操作更新值
     * @param person        修改的对象
     * @param fieldOffset   对象的成员变量相对于对象内存地址的偏移量
     * @param expect        期望值
     * @param value         更新的值
     */
    public static void compareAndSwapObject(Person person, long fieldOffset, Object expect, Object value) {
        unsafe.compareAndSwapObject(person, fieldOffset, expect, value);
    }

    /**
     * CAS操作更新值
     * @param person        修改的对象
     * @param fieldOffset   对象的成员变量相对于对象内存地址的偏移量
     * @param expect        期望值
     * @param value         更新的值
     */
    public static void compareAndSwapInt(Person person, long fieldOffset, int expect, int value) {
        unsafe.compareAndSwapInt(person, fieldOffset, expect, value);
    }

    /**
     * CAS操作更新值
     * @param person        修改的对象
     * @param fieldOffset   对象的成员变量相对于对象内存地址的偏移量
     * @param expect        期望值
     * @param value         更新的值
     */
    public static void compareAndSwapLong(Person person, long fieldOffset, long expect, long value) {
        unsafe.compareAndSwapLong(person, fieldOffset, expect, value);
    }

    /**
     * 将当前线程挂起
     * @param abs       abs==false,表示timeout的时间单位是纳秒
     *                  abs==false && timeout==0 表示线程将一直挂起,直至被恢复或被中断
     * @param timeout   挂起的时间
     */
    public static void park(boolean abs, long timeout) {
        unsafe.park(abs, timeout);
    }

    /**
     * 恢复被挂起的线程
     * @param thread    线程对象
     */
    public static void unpark(Thread thread) {
        unsafe.unpark(thread);
    }


}

执行main方法,结果如下:

类变量[staticStringField]相对于类内存地址的偏移量:104
成员变量[stringField]相对于实例对象内存地址的偏移量:24
成员变量[intField]相对于实例对象内存地址的偏移量:12
成员变量[longField]相对于实例对象内存地址的偏移量:16
初始:Person{staticStringField='null'stringField='null', intField=0, longField=0}
修改之后:Person{staticStringField='staticStringField-value'stringField='stringField-value', intField=1, longField=1}
CAS修改之后:Person{staticStringField='staticStringField-value'stringField='cas-stringField-value', intField=2, longField=2}

 

posted @ 2019-05-22 22:39  狱婪  阅读(164)  评论(0编辑  收藏  举报