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?相关推荐

  1. unsafe java_java Unsafe详细解析

    问题 (1)Unsafe是什么? (2)Unsafe只有CAS的功能吗? (3)Unsafe为什么是不安全的? (4)怎么使用Unsafe? 简介 Unsafe为我们提供了访问底层的机制,这种机制仅供 ...

  2. java unsafe park_java – WAITING at sun.misc.Unsafe.park(Native Method)

    我的一个应用程序在一段负载运行的时间内挂起,有谁知道在jstack中可能会导致这样的输出: "scheduler-5" prio=10 tid=0x00007f49481d0000 ...

  3. unsafehelper java_Java 9中将移除 Sun.misc.Unsafe

    灾难将至,Java 9中将移除 Sun.misc.Unsafe Oracle 正在计划在Java 9中去掉 sun.misc.Unsafe API. 这绝对将是一场灾难,有可能会彻底破坏整个 java ...

  4. Go 学习笔记(74)— Go 标准库之 unsafe

    Go 语言自带的 unsafe 包的高级用法, 顾名思义,unsafe 是不安全的.Go 将其定义为这个包名,也是为了让我们尽可能地不使用它.不过虽然不安全,它也有优势,那就是可以绕过 Go 的内存安 ...

  5. java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类

    是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...

  6. Unsafe工具类的一些实用技巧,通往JVM底层的钥匙

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那 ...

  7. 聊聊Unsafe的一些使用技巧

    记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那时候无疑是兴奋的,瞬间觉得自己脱离了"Java 初学者" ...

  8. Java双刃剑之Unsafe类详解

    前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对Unsafe的态度都是 ...

  9. 面试官:说说 Java 中的 Unsafe 和 CAS

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://urlify.cn/nAVjM ...

最新文章

  1. 【ANDROID游戏开发十六】ANDROID GESTURE之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!...
  2. [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)
  3. 转载------------java equals 方法
  4. java8的新特性_Java8的
  5. 让你脱胎成技术大神的JAVA开发技巧
  6. 3dcaptcha php,php实现的Captcha验证码类实例
  7. Laravel中优雅的验证日期需要大于今天
  8. 机械工程师 舒尔电子_工程师专业分类,原来工程师也能这么“多才多艺”
  9. JAVA语法基础作业——动手动脑以及课后实验性问题 (七)
  10. Excel实验情况对比排序
  11. python最新版安装图集_[python] plist图集拆分小图
  12. 12个免费logo生成器
  13. 《Hive编程指南》阅读笔记
  14. PPT基础(二十二)裁剪图片
  15. 几种边缘检测算子的比较Roberts,Sobel,Prewitt,LOG,Canny
  16. 使用 gzip 压缩数据
  17. 外包公司面试门槛高吗?程序员进外包公司容易吗?
  18. 单相桥式全控整流电路的matlab仿真,基于Matlab的单相桥式全控整流电路的仿真研究...
  19. 4 仓储管理系统 仓库端功能
  20. fetch下载文件--统一拦截导出文件

热门文章

  1. P4313-文理分科【最小割】
  2. 牛客练习赛 57——manacher算法 树形dp?
  3. 【最短路】【SPFA】电车 (luogu 1346)
  4. P3327 约数的个数和 [约数函数性质,数论分块]
  5. Oracle入门(七)之表空间
  6. [编程入门]宏定义的练习:输入两个整数,求他们相除的余数。用带参的宏来实现,编程序。
  7. 新闻发布项目——分页公共类(PageUitl )
  8. java面向对象高级分层实例_接口类
  9. java安装显示更改_java 安装与配置
  10. 系统架构设计师考试 重要的部分