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}
原文:https://www.cnblogs.com/517cn/p/10909051.html