没有合适的资源?快使用搜索试试~ 我知道了~
Java为什么会引入及如何使用Unsafe
0 下载量 197 浏览量
2020-12-22
18:28:06
上传
评论
收藏 69KB PDF 举报
温馨提示
试读
2页
综述 sun.misc.Unsafe至少从2004年Java1.4开始存在于Java中了。在Java9中,为了提高JVM的可维护性,Unsafe和许多其他的东西一起都被作为内部使用类隐藏起来了。但是究竟是什么取代Unsafe不得而知,个人推测会有不止一样来取代它,那么问题来了,到底为什么要使用Unsafe? 做一些Java语言不允许但是又十分有用的事情 很多低级语言中可用的技巧在Java中都是不被允许的。对大多数开发者而言这是件好事,既可以拯救你,也可以拯救你的同事们。同样也使得导入开源代码更容易了,因为你能掌握它们可以造成的大的灾难上限。或者至少明确你可以不小心失误的界限。
资源详情
资源评论
资源推荐
Java为什么会引入及如何使用为什么会引入及如何使用Unsafe
综述
sun.misc.Unsafe至少从2004年Java1.4开始存在于Java中了。在Java9中,为了提高JVM的可维护性,Unsafe和许多其
他的东西一起都被作为内部使用类隐藏起来了。但是究竟是什么取代Unsafe不得而知,个人推测会有不止一样来取代它,那
么问题来了,到底为什么要使用Unsafe?
做一些Java语言不允许但是又十分有用的事情
很多低级语言中可用的技巧在Java中都是不被允许的。对大多数开发者而言这是件好事,既可以拯救你,也可以拯救你
的同事们。同样也使得导入开源代码更容易了,因为你能掌握它们可以造成的大的灾难上限。或者至少明确你可以不小心失误
的界限。如果你尝试地足够努力,你也能造成损害。
那你可能会奇怪,为什么还要去尝试呢?当建立库时,Unsafe中很多(但不是所有)方法都很有用,且有些情况下,除
了使用JNI,没有其他方法做同样的事情,即使它可能会更加危险同时也会失去Java的“一次编译,运行”的跨平台特性。
对象的反序列化
当使用框架反序列化或者构建对象时,会假设从已存在的对象中重建,你期望使用反射来调用类的设置函数,或者更准确
一点是能直接设置内部字段甚至是final字段的函数。问题是你想创建一个对象的实例,但你实际上又不需要构造函数,因为它
可能会使问题更加困难而且会有副作用。
public class A implements Serializable {
private final int num;
public A(int num) {
System.out.println("Hello Mum");
this.num = num;
}
public int getNum() {
return num;
}
}
在这个类中,应该能够重建和设置final字段,但如果你不得不调用构造函数时,它可能做一些和反序列化无关的事情。有
了这些原因,很多库使用Unsafe创建实例而不是调用构造函数。
Unsafe unsafe = getUnsafe();
Class aClass = A.class;
A a = (A) unsafe.allocateInstance(aClass);
调用allocateInstance函数避免了在我们不需要构造函数的时候却调用它。
线程安全的直接获取内存
Unsafe的另外一个用途是线程安全的获取非堆内存。ByteBuffer函数也能使你安全的获取非堆内存或是DirectMemory,
但它不会提供任何线程安全的操作。你在进程间共享数据时使用Unsafe尤其有用。
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class PingPongMapMain {
public static void main(String… args) throws IOException {
boolean odd;
switch (args.length < 1 ? "usage" : args[0].toLowerCase()) {
case "odd":
odd = true;
break;
case "even":
odd = false;
break;
default:
System.err.println("Usage: java PingPongMain [odd|even]");
return;
}
int runs = 10000000;
long start = 0;
System.out.println("Waiting for the other odd/even");
File counters = new File(System.getProperty("java.io.tmpdir"), "counters.deleteme");
counters.deleteOnExit();
try (FileChannel fc = new RandomAccessFile(counters, "rw").getChannel()) {
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
long address = ((DirectBuffer) mbb).address();
for (int i = -1; i < runs; i++) {
for (; ; ) {
weixin_38708105
- 粉丝: 9
- 资源: 866
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0