总览

sun.misc.Unsafe至少在Java 1.4(2004)中就已经存在于Java中。 在Java 9中,不安全将与许多其他供内部使用的类一起隐藏。 以提高JVM的可维护性。 尽管仍不确定究竟将取代Unsafe到底是什么,但我怀疑将取代Unsafe不仅仅是一件事,但它提出了一个问题,为什么要使用它?

执行Java语言不允许的但仍然有用的操作。

Java不允许使用低级语言可用的许多技巧。 对于大多数开发人员而言,这是一件好事,不仅可以使您免于自己,而且还可以使您从同事中免除。 这也使导入开放源代码更加容易,因为您知道它们可以造成的损害是有限的。 或至少可以限制您意外执行的操作。 如果您尽力而为,仍然可能造成伤害。

但是您为什么还要尝试,您可能会感到奇怪? 在不安全的情况下构建库时,很多(但不是全部)方法很有用,并且在某些情况下,如果不使用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

Java如何以及为什么使用Unsafe?相关推荐

  1. JAVA中神奇的双刃剑--Unsafe

    参考资料: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. Java魔法类:sun.misc.Unsafe 在openjdk8下看Unsafe源码 ...

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

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

  3. Java并发编程,无锁CAS与Unsafe类及其并发包Atomic

    为什么80%的码农都做不了架构师?>>>    我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...

  4. 字体对话框java实验_Java Web安全 || Java基础 sun.misc.Unsafe

    点击上方"凌天实验室","星标或置顶公众号" 漏洞.技术还是其他,我都想第一时间和你分享 " [历史]已连载更新全部内容:[菜单栏]-[JAVA SE ...

  5. Java魔法类:Unsafe应用解析

    Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别.不安全操作的方法,如直接访问系统内存资源.自主管理内存资源等,这些方法在提升Java运行效率.增强Java语言底层资源操作能 ...

  6. java unsafe park_Java魔法类——Unsafe应用解析

    前言 Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别.不安全操作的方法,如直接访问系统内存资源.自主管理内存资源等,这些方法在提升Java运行效率.增强Java语言底层资源 ...

  7. 【基本功】Java魔法类:Unsafe应用解析

    总第334篇 2019年 第12篇 大家好,我是程序员鼓励师美美- <基本功>专栏又上新了:Java中的Unsafe类在提升运行效率.增强底层资源操作能力方面有很大的用处.但如果在开发过程 ...

  8. Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...

  9. Java Unsafe 类

    Unsafe类是啥? Java最初被设计为一种安全的受控环境.尽管如此,Java HotSpot还是包含了一个"后门",提供了一些可以直接操控内存和线程的低层次操作.这个后门类-- ...

最新文章

  1. 【金三银四跳槽季】Java工程师如何在1个月内做好面试准备?
  2. 目标检测--Light-Head R-CNN: In Defense of Two-Stage Object Detector
  3. mjpg-streamer在Ubuntu下编译,运行
  4. 小鑫の日常系列故事(十)——排名次_JAVA
  5. Maven实战(八)——常用Maven插件介绍(下)
  6. 工作日报模板_千份财会人通用工作模板:自动核算工资、财务分析报表等等
  7. Android 画布画线,android实现一个简单的画布,可以用手指画线条。
  8. VMware vCenter Server Appliance Photon OS安全修补程序
  9. wpf程序运行时停止工作,事件管理器报错lci_proxyumd32.dll
  10. NSNotificationCenter消息通信机制介绍(KVO)
  11. 今天是雾霾,明天是什么?马尔可夫链告诉你
  12. 赤兔安卓版语音图片资料处理
  13. python用什么数据库比较好_Python和主流数据库
  14. SpringCloud服务器服务注册在Euraka上,访问IP地址问题
  15. envi classic将不同影像裁剪成同一大小
  16. ffmpeg 音频转amr
  17. 【OpenGL学习笔记③】——着色器【GLSL Uniform 彩色三角形 变色正方形】
  18. SUPPA 可变剪切分析
  19. WIN10专业版无法隐藏任务栏图标
  20. C++“打鱼晒网”问题

热门文章

  1. 所有的软弱,都是昂贵的
  2. SpringMVC中使用作用域对象完成数据的流转
  3. java 取随机正整数_Java获取随机数
  4. 检测窥屏_开挂、狙击、窥屏?乱象丛生的炉石狂野天梯,到底怎么了?
  5. mysql的on和in用法_数据库中in、on、with的用法及示例。
  6. (转)linux上nginx源码编译安装
  7. centos上安装jdk
  8. X86汇编语言中的registers相关
  9. GET与POST传递数据的最大长度能够达到多少
  10. jetty java_Jetty,Java和OAuth入门