zoukankan      html  css  js  c++  java
  • Unsafe 的简单使用

    Unsafe 简介

    Unsafe 是sun.misc包中的一个类,可以通过内存偏移量操作类变量/成员变量

    Unsafe 用途

    AQS(AbstractQueuedSynchronizer) 常用作实现轻量级锁,它里面有一个双向链表,用于封装未抢到锁的线程 ,其中有用到UnsafecompareAndSwapObject修改链表

    Unsafe 简单使用示例

    package com.xh.kssfwjg.idgenerator;
    
    import sun.misc.Unsafe;
    
    import java.lang.reflect.Field;
    
    /**
     * TODO
     *
     * @auther xh
     * @date 12/26/18 6:11 PM
     */
    public class UnSaveTest {
        private static final Unsafe unsafe = getUnsafe();
        private static final long objectNameOffset;
        private static final long staticNameOffset;
    
        private static String staticName = "qq";
        private String objectName = "123";
    
        static {
            try {
                objectNameOffset = unsafe.objectFieldOffset
                        (UnSaveTest.class.getDeclaredField("objectName"));
                staticNameOffset = unsafe.staticFieldOffset(UnSaveTest.class.getDeclaredField("staticName"));
            } catch (NoSuchFieldException e) {
                throw new Error(e);
            }
        }
    
        public static void main(String[] args) {
            UnSaveTest unSaveTest = new UnSaveTest();
            // unsafe.compareAndSwapObject(unSaveTest, testOffset, "123", "456");//CAS
            unsafe.putObject(unSaveTest, objectNameOffset, "haha");//直接修改
            unsafe.putObject(UnSaveTest.class, staticNameOffset, "hehe");//直接修改
            System.out.println(unSaveTest.objectName);
            System.out.println(UnSaveTest.staticName);
        }
    
    
        private static Unsafe getUnsafe() {
            Field singleoneInstanceField = null;
            try {
                singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
                singleoneInstanceField.setAccessible(true);
                return (Unsafe) singleoneInstanceField.get(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    

    output:

    haha
    hehe
    

    ps:

    如果变量使用final修饰,如:

    private static final String staticName = "qq";
    private final String objectName = "123";
    

    是不能修改的.

    另外附上反射的示例

            try {
                Class clazz = Class.forName("com.xh.kssfwjg.idgenerator.UnSaveTest");
                Object o = clazz.newInstance();
                Field object_field_name = clazz.getDeclaredField("objectName");
                object_field_name.setAccessible(true);
                object_field_name.set(o, "ooo");
    
                Field static_field_name = clazz.getDeclaredField("staticName");
                static_field_name.setAccessible(true);
                static_field_name.set(clazz, "ppp");
    
                System.out.println(UnSaveTest.staticName);
                System.out.println(((UnSaveTest) o).objectName);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    

    结果一样

  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/lanqie/p/10181363.html
Copyright © 2011-2022 走看看