unsafe java_Java如何以及为什么使用Unsafe?
unsafe java
总览
sun.misc.Unsafe至少在Java 1.4(2004)中就已经存在于Java中。 在Java 9中,不安全性将与许多其他供内部使用的类一起隐藏。 以提高JVM的可维护性。 尽管仍不确定究竟将取代Unsafe到底是什么,但我怀疑将取代Unsafe不仅仅是一件事,但它提出了一个问题,为什么要使用它?
执行Java语言不允许的但仍然有用的操作。
Java不允许使用许多底层语言的技巧。 对于大多数开发人员来说,这是一件好事,不仅可以使您免于自己,还可以使您从同事中免除。 这也使导入开放源代码更加容易,因为您知道它们可能造成的损害是有限的。 或至少可以限制您意外执行的操作。 如果您尽力而为,仍然可能造成伤害。
但是您为什么还要尝试,您可能会感到奇怪? 当在Unsafe中构建库时,很多(但不是全部)方法很有用,并且在某些情况下,如果不使用JNI,则没有其他方法可以做同样的事情,这更危险,并且您将失去“一次编译,在任何地方运行”的权限。 ”
对象反序列化
使用框架反序列化或构建对象时,您要进行假设以重新构成之前存在的对象。 您期望您将使用反射来调用类的setter,或者更可能直接设置内部字段,甚至最终字段。 问题是您想创建一个对象的实例,但是您实际上并不需要构造函数,因为这可能只会使事情变得更加困难并产生副作用。
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使您可以安全地访问堆外或直接内存,但是它没有任何线程安全操作。 如果要在进程之间共享数据,这特别有用。
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 (; ; ) {long value = UNSAFE.getLongVolatile(null, address);boolean isOdd = (value & 1) != 0;if (isOdd != odd)// wait for the other side.continue;// make the change atomic, just in case there is more than one odd/even processif (UNSAFE.compareAndSwapLong(null, address, value, value + 1))break;}if (i == 0) {System.out.println("Started");start = System.nanoTime();}}}System.out.printf("... Finished, average ping/pong took %,d ns%n",(System.nanoTime() - start) / runs);}static final Unsafe UNSAFE;static {try {Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);UNSAFE = (Unsafe) theUnsafe.get(null);} catch (Exception e) {throw new AssertionError(e);}}
}
当您在两个程序中运行此程序时,一个程序带有奇数 ,另一个程序带有偶数 。 您可以看到每个进程都通过持久共享内存来更改数据。
在每个程序中,它会将相同的磁盘高速缓存映射到进程中。 内存中实际上只有一个文件副本。 这意味着可以共享内存,前提是您使用线程安全操作,例如volatile和CAS操作。
i7-3970X的输出为
等待另一个奇/偶
已开始
…完成后,平均ping / pong花费了83 ns
这是两个进程之间的83 ns往返时间。 当您考虑使用System V IPC大约需要2500 ns的时间,并且IPC易变而不是持续存在时,这很快。
使用不安全适合工作吗?
我不建议您直接使用不安全。 它比自然的Java开发需要更多的测试。 因此,我建议您使用已经过使用测试的库。 如果您想自己使用Unsafe,建议您在独立的库中测试它的用法。 这限制了在应用程序中使用“不安全”的方式,并为您提供了一个更安全,不安全的方式。
结论
有趣的是Java中存在Unsafe,您可能想在家中玩它。 它有一些工作应用程序,尤其是在编写低级库时,但是总的来说,最好使用经过测试的Unsafe库,而不是直接使用它。
翻译自: https://www.javacodegeeks.com/2014/12/how-and-why-is-unsafe-used-in-java.html
unsafe java
unsafe java_Java如何以及为什么使用Unsafe?相关推荐
- unsafe java_java Unsafe详细解析
问题 (1)Unsafe是什么? (2)Unsafe只有CAS的功能吗? (3)Unsafe为什么是不安全的? (4)怎么使用Unsafe? 简介 Unsafe为我们提供了访问底层的机制,这种机制仅供 ...
- java unsafe park_java – WAITING at sun.misc.Unsafe.park(Native Method)
我的一个应用程序在一段负载运行的时间内挂起,有谁知道在jstack中可能会导致这样的输出: "scheduler-5" prio=10 tid=0x00007f49481d0000 ...
- unsafehelper java_Java 9中将移除 Sun.misc.Unsafe
灾难将至,Java 9中将移除 Sun.misc.Unsafe Oracle 正在计划在Java 9中去掉 sun.misc.Unsafe API. 这绝对将是一场灾难,有可能会彻底破坏整个 java ...
- Go 学习笔记(74)— Go 标准库之 unsafe
Go 语言自带的 unsafe 包的高级用法, 顾名思义,unsafe 是不安全的.Go 将其定义为这个包名,也是为了让我们尽可能地不使用它.不过虽然不安全,它也有优势,那就是可以绕过 Go 的内存安 ...
- java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类
是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...
- Unsafe工具类的一些实用技巧,通往JVM底层的钥匙
欢迎关注方志朋的博客,回复"666"获面试宝典 前言 记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那 ...
- 聊聊Unsafe的一些使用技巧
记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那时候无疑是兴奋的,瞬间觉得自己脱离了"Java 初学者" ...
- Java双刃剑之Unsafe类详解
前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对Unsafe的态度都是 ...
- 面试官:说说 Java 中的 Unsafe 和 CAS
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://urlify.cn/nAVjM ...
最新文章
- 【ANDROID游戏开发十六】ANDROID GESTURE之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!...
- [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)
- 转载------------java equals 方法
- java8的新特性_Java8的
- 让你脱胎成技术大神的JAVA开发技巧
- 3dcaptcha php,php实现的Captcha验证码类实例
- Laravel中优雅的验证日期需要大于今天
- 机械工程师 舒尔电子_工程师专业分类,原来工程师也能这么“多才多艺”
- JAVA语法基础作业——动手动脑以及课后实验性问题 (七)
- Excel实验情况对比排序
- python最新版安装图集_[python] plist图集拆分小图
- 12个免费logo生成器
- 《Hive编程指南》阅读笔记
- PPT基础(二十二)裁剪图片
- 几种边缘检测算子的比较Roberts,Sobel,Prewitt,LOG,Canny
- 使用 gzip 压缩数据
- 外包公司面试门槛高吗?程序员进外包公司容易吗?
- 单相桥式全控整流电路的matlab仿真,基于Matlab的单相桥式全控整流电路的仿真研究...
- 4 仓储管理系统 仓库端功能
- fetch下载文件--统一拦截导出文件