首页 > 技术 > 编程 > Java > 可以做到你想做到的一切的 java unsafe

可以做到你想做到的一切的 java unsafe


自己由于对netty底层代码的一些拜读,还有一切里面的代码有些是借鉴github大神,自己整理出来为了以后可以用的,分享出来,大家学习学习。程序的至理名言:越是地层越是高效,上层越是抽象越是简单。所以分享下java unsafe这个类。编辑器编译不会通过的,要调一下编辑器的配置,具体我也忘啦,google在手天下我有,自己搞搞。
这个是测试类,里面只有几个内容,有点没体现unsafe的强大,自己可以发掘下。

package com.demo;

import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeTest {
      public static void main(String[] args) throws Exception{

           Unsafe unsafe =UnsafeHelper.getUnsafe();
           long address=unsafe.allocateMemory(1);
           unsafe.putChar(address,'a');
           //可以取到任何一个类的实例,不管有什么样的构造器。
           Student student=(Student)unsafe.allocateInstance(Student.class);
           System.out.println(UnsafeHelper.toAddress(student));
              student.setName("lisi");
              student.setAge(18);
              for(Field field:Student.class.getDeclaredFields()){  
                  System.out.println(field.getName()+":对应的内存偏移地址"+unsafe.objectFieldOffset(field));  
              }  
              System.out.println("-------"+unsafe.getAddress(UnsafeHelper.toAddress(student))+"------------");  
              int ageOffset= 8; 
              //下面演示的是变量的原子操作,不可打断。
              //修改内存偏移地址为8的值(age),返回true,说明通过内存偏移地址修改age的值成功  
              System.out.println(unsafe.compareAndSwapInt(student, ageOffset, 18, 20));  
              System.out.println("age修改后的值:"+student.getAge());  
              System.out.println("-------------------");  

              //修改内存偏移地址为8的值,但是修改后不保证立马能被其他的线程看到。  
              unsafe.putOrderedInt(student, 8, 33);  
              System.out.println("age修改后的值:"+student.getAge());  
              System.out.println("-------------------");  

              //修改内存偏移地址为12的值,volatile修饰,修改能立马对其他线程可见  
              unsafe.putObjectVolatile(student, 12, "han mei");  
              System.out.println("name修改后的值:"+unsafe.getObjectVolatile(student, 12));
       }
    }
    class Student{
        private String name;

        private int age;

        private Student(){
            System.out.println("============");
        }



        public int getAge() {
            return age;
        }



        public void setAge(int age) {
            this.age = age;
        }



        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

无所不能的unsafe工具类,这个是重点可以好好自己上手试试。

package com.demo;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;

import sun.misc.Unsafe;

public class UnsafeHelper {
    private static final Unsafe unsafe = createUnsafe();

      private static Unsafe createUnsafe() {
        try {
          Field field = Unsafe.class.getDeclaredField("theUnsafe");
          field.setAccessible(true);
          return (Unsafe) field.get(null);
        } catch (Exception e) {
          throw new RuntimeException("Can't use unsafe", e);
        }
      }

      public static Unsafe getUnsafe() {
        return unsafe;
      }

      public static long toAddress(Object obj) {
            Object[] array = new Object[] {obj};
            long baseOffset = unsafe.arrayBaseOffset(Object[].class);
            return normalize(unsafe.getInt(array, baseOffset));
          }
      private static long normalize(int value) {
            if (value >= 0) {
              return value;
            }
            return (~0L >>> 32) & value;
          }
      public static long sizeOf(Object o) {
            Unsafe u = getUnsafe();
            HashSet<Field> fields = new HashSet<Field>();
            Class<?> c = o.getClass();
            while (c != Object.class) {
                for (Field f : c.getDeclaredFields()) {
                    if ((f.getModifiers() & Modifier.STATIC) == 0) {
                        fields.add(f);
                    }
                }
                c = c.getSuperclass();
            }
            // get offset
            long maxSize = 0;
            for (Field f : fields) {
                long offset = u.objectFieldOffset(f);
                if (offset > maxSize) {
                    maxSize = offset;
                }
            }
            return ((maxSize/8) + 1) * 8;   // padding
        }

        public  static Object fromAddress(long address) {
                Object[] array = new Object[] {null};
                long baseOffset = getUnsafe().arrayBaseOffset(Object[].class);
                getUnsafe().putLong(array, baseOffset, address);
                return array[0];
            }

        public  static Object shallowCopy(Object obj) {
                long size = sizeOf(obj);
                long start = toAddress(obj);
                long address = getUnsafe().allocateMemory(size);
                getUnsafe().copyMemory(start, address, size);
                return fromAddress(address);
            }
}

第一次写,请见谅,就想整理出来,那天要用的时候可以找到。

感谢关注 Ithao123Java频道,ithao123.cn是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!

关键词:

精选专题

Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。

Hadoop是一个由Apache基金会所开发的分布式系统基础架构。 用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。 Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。 Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。

产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计

随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责