为什么会存在sun.misc.Unsafe类,它在现实世界中如何使用?

276

我最近了解到sun.misc.Unsafe包,惊讶于它所能实现的功能。

当然,该类未被记录在文档中,但我想知道是否有使用它的充分理由。在哪些情况下可能需要使用它?在现实世界的场景中,它可能如何使用?

此外,如果您确实需要它,这是否不表示您的设计可能存在问题?

为什么Java甚至要包括这个类?


7
JDK 的开发人员目前正在审查此 API,以确定是否将其转换为 Java 9 中的公共 API。如果您使用它,值得花费 5 分钟填写调查问卷:https://www.surveymonkey.com/s/sun-misc-Unsafe。 - Andy Lynch
2
这篇帖子正在meta上讨论:http://meta.stackoverflow.com/questions/299139/what-to-do-with-close-open-wars - Jon Clements
16个回答

5
我们已经使用Unsafe实现了大量的集合,例如Arrays、HashMaps和TreeMaps。
为了避免/减少碎片化,我们使用dlmalloc的概念在不安全的情况下实现了内存分配器。
这帮助我们在并发性能方面获得了提升。

3

使用Unsafe.park()Unsafe.unpark()可以构建自定义并发控制结构和协作调度机制。


25
可以翻译为:作为java.util.concurrent.locks.LockSupport公开可用。 - bestsss

1

1
如果您需要替换当前使用它的类提供的功能,那么就需要它。
这可以是定制/更快/更紧凑的序列化/反序列化,更快/更大的缓冲区/可调整大小的ByteBuffer版本,或添加一个目前不支持的原子变量。
我曾经在某个时候使用过它来完成所有这些任务。

1
我自己没有使用过,但我认为如果您有一个变量只偶尔被多个线程读取(因此您不想使其成为volatile),则可以在主线程中写入时使用putObjectVolatile,并在其他线程进行稀有读取时使用readObjectVolatile

1
但是根据下面线程中的讨论,不可满足的volatile变量几乎与非volatile变量一样快。http://stackoverflow.com/questions/5573782/is-volatile-of-no-use-on-x86-processors - pdeva
不能用普通的写入和读取替换volatile语义...这是灾难的配方,因为它可能在一个环境中工作,但在另一个环境中不起作用。如果您想要使用单个编写线程的volatile语义,可以在编写线程上使用AtomicReference.lazySet,并在读者上使用get()(有关该主题的讨论,请参见此帖子)。volatile读取相对便宜,但不是免费的,请参见此处 - Nitsan Wakart
“...当你写它时,可以使用putObjectVolatile…” 我并不建议使用普通的写入方式。 - Matt Wonlaw

0

该对象似乎能够在比Java代码通常允许的更低级别上工作。如果您正在编写高级应用程序,则JVM会将内存处理和其他操作抽象化,使编程更加容易。通过使用Unsafe库,您实际上正在完成通常为您完成的低级操作。

正如woliveirajr所述,“random()”使用Unsafe进行种子生成,就像许多其他操作将使用Unsafe中包含的allocateMemory()函数一样。

作为程序员,您可能永远不需要使用此库,但对低级元素进行严格控制确实很方便(这就是为什么主要产品中仍然存在汇编语言和(在较小程度上)C代码的原因)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接