How and Why Unsafe is Used in Java---reference
By Peter Lawrey
https://www.voxxed.com/blog/2014/12/how-and-why-unsafe-is-used-in-java/
Overview
sun.misc.Unsafe has been in Java from at least as far back as Java 1.4 (2004). In Java 9, Unsafe will be hidden along with many other, for-internal-use classes. to improve the maintainability of the JVM. While it is still unclear exactly what will replace Unsafe, and I suspect it will be more than one thing which replaces it, it raises the question, why is it used at all?
Doing things which the Java language doesn’t allow but are still useful.
Java doesn’t allow many of the tricks which are available to lower level languages. For most developers this is very good thing, and it not only saves you from yourself, it also saves you from your co-workers. It also makes it easier to import open source code because you know there is limits to how much damage they can do. Or at least there is limits to how much you can do accidentally. If you try hard enough you can still do damage.
But why would you even try, you might wonder? When building libraries many (but not all) of the methods in Unsafe are useful and in some cases, there is no other way to do the same thing without using JNI, which is even more dangerous and you lose the “compile once, run anywhere”
Deserialization of objects
|
1
2
3
4
5
6
7
8
9
10
11
|
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; }} |
In this class, you should be able to rebuild and set the final field, but if you have to call a constructor and it might do things which don’t have anything to do with deserialization. For these reasons many libraries use Unsafe to create instances without calling a constructor
|
1
2
3
|
Unsafe unsafe = getUnsafe();Class aClass = A.class;A a = (A) unsafe.allocateInstance(aClass); |
Calling allocateInstance avoids the need to call the appropriate constructor, when we don’t need one.
Thread safe access to direct memory
Another use for Unsafe is thread safe access to off heap memory. ByteBuffer gives you safe access to off heap or direct memory, however it doesn’t have any thread safe operations. This is particularly useful if you want to share data between processes.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
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 process if (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); } }} |
When you run this in two programs, one with odd and the other with even. You can see that each process is changing data via persisted shared memory.
In each program it maps the same are of the disks cache into the process. There is actually only one copy of the file in memory. This means the memory can be shared, provided you use thread safe operations such as the volatile and CAS operations.
The output on an i7-3970X is
Waiting for the other odd/even
Started
… Finished, average ping/pong took 83 ns
That is 83 ns round trip time between two processes. When you consider System V IPC takes around 2,500 ns and IPC volatile instead of persisted, that is pretty quick.
Is using Unsafe suitable for work?
Conclusion
How and Why Unsafe is Used in Java---reference的更多相关文章
- Java Reference核心原理分析
本文转载自Java Reference核心原理分析 导语 带着问题,看源码针对性会更强一点.印象会更深刻.并且效果也会更好.所以我先卖个关子,提两个问题(没准下次跳槽时就被问到). 我们可以用Byte ...
- Java Reference简要概述
@(Java)[Reference] Java Reference简要概述 Reference对象封装了其它对象的引用,可以和普通的对象一样操作. Java提供了四种不同类型的引用,引用级别从高到低分 ...
- Java Reference 源码分析
@(Java)[Reference] Java Reference 源码分析 Reference对象封装了其它对象的引用,可以和普通的对象一样操作,在一定的限制条件下,支持和垃圾收集器的交互.即可以使 ...
- java Reference
相关讲解,参考: Java Reference 源码分析 Java Reference详解 Reference: // 名称说明下:Reference指代引用对象本身,Referent指代被引用对象 ...
- Java Reference & ReferenceQueue一览
Overview The java.lang.ref package provides more flexible types of references than are otherwise ava ...
- Implementing the skip list data structure in java --reference
reference:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html The link ...
- 理解java reference
Java世界泰山北斗级大作<Thinking In Java>切入Java就提出“Everything is Object”.在Java这个充满Object的世界中,reference是一 ...
- What Influences Method Call Performance in Java?--reference
reference from:https://www.voxxed.com/blog/2015/02/too-fast-too-megamorphic-what-influences-method-c ...
- Why String is immutable in Java ?--reference
String is an immutable class in Java. An immutable class is simply a class whose instances cannot be ...
- java Reference(摘录)
Java中的Reference对象和GC是紧密联系在一起的,Reference的实现也是和GC相关的. 强引用 强引用是Java中使用最普遍的引用,我们经常使用的Object o = new Obje ...
随机推荐
- zigbee智能家居基础扫盲
zigbee Zigbee是基于IEEE802.15.4标准的低功耗个域网协议.根据这个协议规定的技术是一种短距离.低功耗的无线通信技术.这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和&qu ...
- Java SE/ME/EE的概念介绍
转自 Java SE/ME/EE的概念介绍 多数编程语言都有预选编译好的类库以支持各种特定的功能,在Java中,类库以包(package)的形式提供,不同版本的Java提供不同的包,以面向特定的应用. ...
- 不重复查询mysql
select EquipmentSID,MIN(MatureTime),MIN(ISlock) from table group by name String sql =” Select * from ...
- webview调用javascript脚本无反应
最近遇到一个问题:在html中有一段javascript脚本定义了一个方法,在使用webview.loadUrl("javascript:方法名()")时方法未执行,后来 查资料发 ...
- JAVA用geotools读写shape格式文件
转自:http://toplchx.iteye.com/blog/1335007 JAVA用geotools读写shape格式文件 (对应geotools版本:2.7.2) (后面添加对应geotoo ...
- ASP.NET (HttpModule,HttpHandler)
asp.net 事件模型机制 ----------------------- 一 客户的请求页面由aspnet_isapi.dll这个动态连接库来处理,把请求的aspx文件发送给CLR进行编译执行,然 ...
- MFC DialogBar 按钮灰色不响应
在MFC单文档加添加DialogBar,然后在DialogBar上添加按钮,会出现如下情况,单击无响应. 解决方案: 在 CSideDialogBar头文件和CPP文件里添加如下函数 afx_msg ...
- HDOJ/HDU 1022 Train Problem I(模拟栈)
Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot o ...
- Java异常错误的面试题及答案
1) Java中什么是Exception? 这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问.我从来没见过面高级或者资深工程师的 时候有人问这玩意,但是对于菜鸟,是很愿意问这个的.简单来说, ...
- Tyvj P3119 核电站问题 动态规划
题目:http://tyvj.cn/p/3119 P3119 核电站问题 时间: 1000ms / 空间: 65536KiB / Java类名: Main 描述 一个核电站有N个放核物质的坑,坑排列在 ...