zoukankan      html  css  js  c++  java
  • 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}
  • 相关阅读:
    JAVA消息对话框
    stringbuffer capacity()的疑问
    JAVA确认对话框
    c/c++实现获取NOD32升级账号密码
    复制构造函数(拷贝构造函数)
    使用VC将sqlite3.def转化为sqlite3.lib
    Windows下安装OpenSSL
    java中io与nio的使用
    使用 XStream 把 Java 对象序列化为 XML
    使用 XStream 把 Java 对象序列化为 XML
  • 原文地址:https://www.cnblogs.com/517cn/p/10909051.html
Copyright © 2011-2022 走看看