1.简介
Unsafe是java中一个强有力的工具类,很多高性能框架都用到了它,并且在我们常用的ConcurrentHashMap,AtomicInteger类中也用到了它。
ConcurrentHashMap.java中:
AtomicInteger.java中:
高性能框架中(包括但不限于):
- Netty
- Hazelcast
- Cassandra
- Mockito / EasyMock / JMock / PowerMock
- Scala Specs
- Spock
- Robolectric
- Grails
- Neo4j
- Spring Framework
- Akka
- Apache Kafka
- Apache Wink
- Apache Storm
- Apache Hadoop
- Apache Continuum
refer:https://blog.dripstat.com/removal-of-sun-misc-unsafe-a-disaster-in-the-making/
refer:https://adtmag.com/blogs/watersworks/2015/08/java-9-hack.aspx
这个类强大之处在于可以像C的指针一样,直接操作内存。正如它的名字一样,它是不安全的,如果处理不好,会导致程序问题发生的概率增大,官方也不建议使用。
2.限制
Unsafe内部使用的是单例模式,通过其静态方法getUnsafe方法获取,但是有些限制,那就是只有系统类加载器可以加载这个类,其他加载器加载会抛出异常,这个我们可以通过看源码来证明:
但是这个限制也只是普通限制,别忘了java还有一个更强大的特性:反射(reflect)。如果你也想试一试这个类,可以通过下面的方法获取其实例:1
2
3Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
里面具体有哪些方法,读者可以自己去源码看下,但是这个类没有官方文档,仅有的是源码上的注释,不过可以通过自己试验来了解和验证其功能。我这里找到一个blog,博主详细介绍了Unsafe中的方法,有兴趣可以去看下:http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/。
3.移除
Unfortunately,oracle计划在jdk1.9中移除它,而且是没有原因的。下面的是Oracle邮件中部分内容:
Let me be blunt – sun.misc.Unsafe must die in a fire. It is – wait
for it – Unsafe. It must go. Ignore any kind of theoretical rope and
start the path to righteousness
refer:https://blog.dripstat.com/removal-of-sun-misc-unsafe-a-disaster-in-the-making/
如果直接移除的话,必然导致很多框架不得不修改源码以让其可以正常运行,不然就没法使用。
就像java8中使用java.time
包来代替java.util
中Date类一样,提供一个过渡期,不强制移除Unsafe类,而是在启动JVM的时候提供一个开关,这个开启的时候我们才可以使用Unsafe,默认是关闭的。