日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

unsafe java_Java如何以及为什么使用Unsafe?

發(fā)布時(shí)間:2023/12/3 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unsafe java_Java如何以及为什么使用Unsafe? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

unsafe java

總覽

sun.misc.Unsafe至少在Java 1.4(2004)中就已經(jīng)存在于Java中。 在Java 9中,不安全性將與許多其他供內(nèi)部使用的類(lèi)一起隱藏。 以提高JVM的可維護(hù)性。 盡管仍不確定究竟將取代Unsafe到底是什么,但我懷疑將取代Unsafe不僅僅是一件事,但它提出了一個(gè)問(wèn)題,為什么要使用它?

執(zhí)行Java語(yǔ)言不允許的但仍然有用的操作。

Java不允許使用許多底層語(yǔ)言的技巧。 對(duì)于大多數(shù)開(kāi)發(fā)人員來(lái)說(shuō),這是一件好事,不僅可以使您免于自己,還可以使您從同事中免除。 這也使導(dǎo)入開(kāi)放源代碼更加容易,因?yàn)槟浪鼈兛赡茉斐傻膿p害是有限的。 或至少可以限制您意外執(zhí)行的操作。 如果您盡力而為,仍然可能造成傷害。

但是您為什么還要嘗試,您可能會(huì)感到奇怪? 當(dāng)在Unsafe中構(gòu)建庫(kù)時(shí),很多(但不是全部)方法很有用,并且在某些情況下,如果不使用JNI,則沒(méi)有其他方法可以做同樣的事情,這更危險(xiǎn),并且您將失去“一次編譯,在任何地方運(yùn)行”的權(quán)限。 ”

對(duì)象反序列化

使用框架反序列化或構(gòu)建對(duì)象時(shí),您要進(jìn)行假設(shè)以重新構(gòu)成之前存在的對(duì)象。 您期望您將使用反射來(lái)調(diào)用類(lèi)的setter,或者更可能直接設(shè)置內(nèi)部字段,甚至最終字段。 問(wèn)題是您想創(chuàng)建一個(gè)對(duì)象的實(shí)例,但是您實(shí)際上并不需要構(gòu)造函數(shù),因?yàn)檫@可能只會(huì)使事情變得更加困難并產(chǎn)生副作用。

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;} }

在該類(lèi)中,您應(yīng)該能夠重建和設(shè)置final字段,但是如果您必須調(diào)用構(gòu)造函數(shù),并且它可能完成與反序列化無(wú)關(guān)的事情。 由于這些原因,許多庫(kù)使用Unsafe來(lái)創(chuàng)建實(shí)例而不調(diào)用構(gòu)造函數(shù)。

Unsafe unsafe = getUnsafe(); Class aClass = A.class; A a = (A) unsafe.allocateInstance(aClass);

不需要時(shí),調(diào)用allocateInstance可以避免調(diào)用適當(dāng)?shù)臉?gòu)造函數(shù)。

線程安全訪問(wèn)直接內(nèi)存

Unsafe的另一個(gè)用途是對(duì)堆外內(nèi)存的線程安全訪問(wèn)。 ByteBuffer使您可以安全地訪問(wèn)堆外或直接內(nèi)存,但是它沒(méi)有任何線程安全操作。 如果要在進(jìn)程之間共享數(shù)據(jù),這特別有用。

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);}} }

當(dāng)您在兩個(gè)程序中運(yùn)行此程序時(shí),一個(gè)程序帶有奇數(shù) ,另一個(gè)程序帶有偶數(shù) 。 您可以看到每個(gè)進(jìn)程都通過(guò)持久共享內(nèi)存來(lái)更改數(shù)據(jù)。

在每個(gè)程序中,它會(huì)將相同的磁盤(pán)高速緩存映射到進(jìn)程中。 內(nèi)存中實(shí)際上只有一個(gè)文件副本。 這意味著可以共享內(nèi)存,前提是您使用線程安全操作,例如volatile和CAS操作。

i7-3970X的輸出為

等待另一個(gè)奇/偶
已開(kāi)始
…完成后,平均ping / pong花費(fèi)了83 ns

這是兩個(gè)進(jìn)程之間的83 ns往返時(shí)間。 當(dāng)您考慮使用System V IPC大約需要2500 ns的時(shí)間,并且IPC易變而不是持續(xù)存在時(shí),這很快。

使用不安全適合工作嗎?

我不建議您直接使用不安全。 它比自然的Java開(kāi)發(fā)需要更多的測(cè)試。 因此,我建議您使用已經(jīng)過(guò)使用測(cè)試的庫(kù)。 如果您想自己使用Unsafe,建議您在獨(dú)立的庫(kù)中測(cè)試它的用法。 這限制了在應(yīng)用程序中使用“不安全”的方式,并為您提供了一個(gè)更安全,不安全的方式。

結(jié)論

有趣的是Java中存在Unsafe,您可能想在家中玩它。 它有一些工作應(yīng)用程序,尤其是在編寫(xiě)低級(jí)庫(kù)時(shí),但是總的來(lái)說(shuō),最好使用經(jīng)過(guò)測(cè)試的Unsafe庫(kù),而不是直接使用它。

翻譯自: https://www.javacodegeeks.com/2014/12/how-and-why-is-unsafe-used-in-java.html

unsafe java

總結(jié)

以上是生活随笔為你收集整理的unsafe java_Java如何以及为什么使用Unsafe?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。