美文网首页
Unsafe的使用解析

Unsafe的使用解析

作者: braveheart075 | 来源:发表于2018-12-10 21:54 被阅读0次

相信很多人都阅读过jdk源码,这两天在看一段代码都时候正好用到Unsafe(JRE的rt.jar中提供了一个类sun.misc.Unsafe),特地研究了下Unsafe这个类。基于对象内存来进行操作对象。不安全。所以不建议使用。特别在concurrent包中都Atomicxxx类,底层都CAS 都用到了这个类。那么这个类究竟能干什么,我们先从实例化开始:

  • 首先,这个类是不能直接实例化到,但是可以通过反射来获取。
        sun.misc.Unsafe U = null;

        Field theUnsafeInstance = null;
        try {
            theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafeInstance.setAccessible(true);
            U = (Unsafe) theUnsafeInstance.get(Unsafe.class);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
  • 其次,我们一般会用到这个类到compareAndSwapXXX,这个方法是干嘛用的?官网解释如下: Screen Shot 2018-12-10 at 9.43.36 PM.png

    就是根据对象在内存的offset(我们叫他偏移量),来比较你期望的值和内存值是否相等,如果相等返回true,并进行swap,用最后一个x来进行swap。

  • 那么,我们来演示下:
    建一个对象:

public class Main {


    private String s;
    private long s1;
    private long s2;

    public static void main(String[] args) {
        Main main = new Main();
        main.s1 = 20;
        long s, next;
        long state = 256;
        System.out.println(1 << 6);
        System.out.println(1 << 10);
        System.out.println(1L << 7);
        System.out.println("Hello World!");
        long except = 1;
        long real = 1;
        sun.misc.Unsafe U = null;

        Field theUnsafeInstance = null;
        try {
            theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafeInstance.setAccessible(true);
            U = (Unsafe) theUnsafeInstance.get(Unsafe.class);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        System.out.println("========");

//        Arrays.stream(Main.class.getDeclaredFields()).forEach(field -> System.out.println(U.objectFieldOffset(field.getName())));

        Field[] fields = Main.class.getDeclaredFields();
        for(Field field : fields) {

            System.out.println(field.getName()+ "=="+ U.objectFieldOffset(field));
        }


        System.out.println("========");


        boolean flag = U.compareAndSwapLong(main,16,21,21);
        System.out.println(flag);
        System.out.println(main.s1);

    }
}
  • 我们看到了这个代码,有三个field。如何获得这三个field?如下这段代码发挥作用:
Field[] fields = Main.class.getDeclaredFields();
  • 获取对象的偏移量:
        for(Field field : fields) {

            System.out.println(field.getName()+ "=="+ U.objectFieldOffset(field));
        }

打印出来的结果如下:

s==12
s1==16
s2==24

这个数字就是offset。那么我们可以验证这个compare方法了。

  • 验证compare方法:我们将offset为16的内存变量s1改成21(原先是20)
boolean flag = U.compareAndSwapLong(main,16,20,21);
System.out.println(flag);
System.out.println(main.s1);

就是比较偏移量为16的内存对象值是否是20,如果是,改成21,打印结果如下:

true
21

可以看到,如预期。好了,大家都知道类似的方法怎么用了吧。期望对大家有帮助。

相关文章

  • Unsafe的使用解析

    相信很多人都阅读过jdk源码,这两天在看一段代码都时候正好用到Unsafe(JRE的rt.jar中提供了一个类su...

  • iOS内存管理

    __unsafe_unratained 修饰符的变量 使用__unsafe_unretained 使用的对象 必须...

  • Netty源码学习(6)--pipeline学习2

    Unsafe unsafe是不安全的意思,不要在应用程序里面直接使用Unsafe以及他的衍生类对象。Unsafe ...

  • Unsafe 应用解析

    Unsafe 是位于 sun.misc 包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统...

  • Java Unsafe CAS 小试

    Unsafe 在 Java 标准库和框架中被大量使用,本文主要介绍如何使用 sun.misc.Unsafe 包实现...

  • Java并发 - Unsafe与LockSupport

    1,Unsafe简介 1)通过Unsafe类可以分配、释放内存。如DirectByteBuffer底层使用unsa...

  • go常用包——unsafe

    unsafe 1 unsafe包简介 unsafe包顾名思义,是非安全的,是面向编译器的一个包,使用它要特别小心,...

  • (美团技术)Java魔法类:Unsafe应用解析

    Java魔法类:Unsafe应用解析[https://tech.meituan.com/2019/02/14/ta...

  • Unsafe类源码解析

    前言 Unsafe,顾名思义,一个不安全的类,那么jdk的开发者为什么要设计一个不安全的类呢?这个类为什么会不安全...

  • 2019-05-19

    Java魔法类:Unsafe应用解析 【求助】ES集群大量数据存储问题 你真的懂“抓包”吗?

网友评论

      本文标题:Unsafe的使用解析

      本文链接:https://www.haomeiwen.com/subject/vufjhqtx.html