一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 簡(jiǎn)單談一談Java中的Unsafe類(lèi)

簡(jiǎn)單談一談Java中的Unsafe類(lèi)

2021-05-04 14:02pkufork Java教程

其實(shí)Java官方不推薦使用Unsafe類(lèi),因?yàn)楣俜秸J(rèn)為,這個(gè)類(lèi)別人很難正確使用,非正確使用會(huì)給JVM帶來(lái)致命錯(cuò)誤。但還是要會(huì)使用,下面這篇文章就來(lái)給大家簡(jiǎn)單的談一談關(guān)于Java中Unsafe類(lèi)的相關(guān)資料,需要的朋友可以參考下

unsafe類(lèi)是啥?

java最初被設(shè)計(jì)為一種安全的受控環(huán)境。盡管如此,java hotspot還是包含了一個(gè)“后門(mén)”,提供了一些可以直接操控內(nèi)存和線(xiàn)程的低層次操作。這個(gè)后門(mén)類(lèi)——sun.misc.unsafe——被jdk廣泛用于自己的包中,如java.nio和java.util.concurrent。但是絲毫不建議在生產(chǎn)環(huán)境中使用這個(gè)后門(mén)。因?yàn)檫@個(gè)api十分不安全、不輕便、而且不穩(wěn)定。這個(gè)不安全的類(lèi)提供了一個(gè)觀察hotspot jvm內(nèi)部結(jié)構(gòu)并且可以對(duì)其進(jìn)行修改。有時(shí)它可以被用來(lái)在不適用c++調(diào)試的情況下學(xué)習(xí)虛擬機(jī)內(nèi)部結(jié)構(gòu),有時(shí)也可以被拿來(lái)做性能監(jiān)控和開(kāi)發(fā)工具。

引言

最近在看java并發(fā)包的源碼,發(fā)現(xiàn)了神奇的unsafe類(lèi),仔細(xì)研究了一下,在這里跟大家分享一下。

簡(jiǎn)單談一談Java中的Unsafe類(lèi)

unsafe類(lèi)是在sun.misc包下,不屬于java標(biāo)準(zhǔn)。但是很多java的基礎(chǔ)類(lèi)庫(kù),包括一些被廣泛使用的高性能開(kāi)發(fā)庫(kù)都是基于unsafe類(lèi)開(kāi)發(fā)的,比如netty、cassandra、hadoop、kafka等。unsafe類(lèi)在提升java運(yùn)行效率,增強(qiáng)java語(yǔ)言底層操作能力方面起了很大的作用。

簡(jiǎn)單談一談Java中的Unsafe類(lèi)

簡(jiǎn)單談一談Java中的Unsafe類(lèi)

unsafe類(lèi)使java擁有了像c語(yǔ)言的指針一樣操作內(nèi)存空間的能力,同時(shí)也帶來(lái)了指針的問(wèn)題。過(guò)度的使用unsafe類(lèi)會(huì)使得出錯(cuò)的幾率變大,因此java官方并不建議使用的,官方文檔也幾乎沒(méi)有。oracle正在計(jì)劃從java 9中去掉unsafe類(lèi),如果真是如此影響就太大了。

簡(jiǎn)單談一談Java中的Unsafe類(lèi)

通常我們最好也不要使用unsafe類(lèi),除非有明確的目的,并且也要對(duì)它有深入的了解才行。要想使用unsafe類(lèi)需要用一些比較tricky的辦法。unsafe類(lèi)使用了單例模式,需要通過(guò)一個(gè)靜態(tài)方法getunsafe()來(lái)獲取。但unsafe類(lèi)做了限制,如果是普通的調(diào)用的話(huà),它會(huì)拋出一個(gè)securityexception異常;只有由主類(lèi)加載器加載的類(lèi)才能調(diào)用這個(gè)方法。其源碼如下:

?
1
2
3
4
5
6
7
8
public static unsafe getunsafe() {
 class var0 = reflection.getcallerclass();
 if(!vm.issystemdomainloader(var0.getclassloader())) {
  throw new securityexception("unsafe");
 } else {
  return theunsafe;
 }
}

網(wǎng)上也有一些辦法來(lái)用主類(lèi)加載器加載用戶(hù)代碼,比如設(shè)置bootclasspath參數(shù)。但更簡(jiǎn)單方法是利用java反射,方法如下:

?
1
2
3
field f = unsafe.class.getdeclaredfield("theunsafe");
f.setaccessible(true);
unsafe unsafe = (unsafe) f.get(null);

獲取到unsafe實(shí)例之后,我們就可以為所欲為了。unsafe類(lèi)提供了以下這些功能:

一、內(nèi)存管理。包括分配內(nèi)存、釋放內(nèi)存等。

該部分包括了allocatememory(分配內(nèi)存)、reallocatememory(重新分配內(nèi)存)、copymemory(拷貝內(nèi)存)、freememory(釋放內(nèi)存 )、getaddress(獲取內(nèi)存地址)、addresssize、pagesize、getint(獲取內(nèi)存地址指向的整數(shù))、getintvolatile(獲取內(nèi)存地址指向的整數(shù),并支持volatile語(yǔ)義)、putint(將整數(shù)寫(xiě)入指定內(nèi)存地址)、putintvolatile(將整數(shù)寫(xiě)入指定內(nèi)存地址,并支持volatile語(yǔ)義)、putorderedint(將整數(shù)寫(xiě)入指定內(nèi)存地址、有序或者有延遲的方法)等方法。getxxx和putxxx包含了各種基本類(lèi)型的操作。

利用copymemory方法,我們可以實(shí)現(xiàn)一個(gè)通用的對(duì)象拷貝方法,無(wú)需再對(duì)每一個(gè)對(duì)象都實(shí)現(xiàn)clone方法,當(dāng)然這通用的方法只能做到對(duì)象淺拷貝。

二、非常規(guī)的對(duì)象實(shí)例化。

allocateinstance()方法提供了另一種創(chuàng)建實(shí)例的途徑。通常我們可以用new或者反射來(lái)實(shí)例化對(duì)象,使用allocateinstance()方法可以直接生成對(duì)象實(shí)例,且無(wú)需調(diào)用構(gòu)造方法和其它初始化方法。

這在對(duì)象反序列化的時(shí)候會(huì)很有用,能夠重建和設(shè)置final字段,而不需要調(diào)用構(gòu)造方法。

三、操作類(lèi)、對(duì)象、變量。

這部分包括了staticfieldoffset(靜態(tài)域偏移)、defineclass(定義類(lèi))、defineanonymousclass(定義匿名類(lèi))、ensureclassinitialized(確保類(lèi)初始化)、objectfieldoffset(對(duì)象域偏移)等方法。

通過(guò)這些方法我們可以獲取對(duì)象的指針,通過(guò)對(duì)指針進(jìn)行偏移,我們不僅可以直接修改指針指向的數(shù)據(jù)(即使它們是私有的),甚至可以找到j(luò)vm已經(jīng)認(rèn)定為垃圾、可以進(jìn)行回收的對(duì)象。

四、數(shù)組操作。

這部分包括了arraybaseoffset(獲取數(shù)組第一個(gè)元素的偏移地址)、arrayindexscale(獲取數(shù)組中元素的增量地址)等方法。arraybaseoffset與arrayindexscale配合起來(lái)使用,就可以定位數(shù)組中每個(gè)元素在內(nèi)存中的位置。

由于java的數(shù)組最大值為integer.max_value,使用unsafe類(lèi)的內(nèi)存分配方法可以實(shí)現(xiàn)超大數(shù)組。實(shí)際上這樣的數(shù)據(jù)就可以認(rèn)為是c數(shù)組,因此需要注意在合適的時(shí)間釋放內(nèi)存。

五、多線(xiàn)程同步。包括鎖機(jī)制、cas操作等。

這部分包括了monitorenter、trymonitorenter、monitorexit、compareandswapint、compareandswap等方法。

其中monitorenter、trymonitorenter、monitorexit已經(jīng)被標(biāo)記為deprecated,不建議使用。

unsafe類(lèi)的cas操作可能是用的最多的,它為java的鎖機(jī)制提供了一種新的解決辦法,比如atomicinteger等類(lèi)都是通過(guò)該方法來(lái)實(shí)現(xiàn)的。compareandswap方法是原子的,可以避免繁重的鎖機(jī)制,提高代碼效率。這是一種樂(lè)觀鎖,通常認(rèn)為在大部分情況下不出現(xiàn)競(jìng)態(tài)條件,如果操作失敗,會(huì)不斷重試直到成功。

六、掛起與恢復(fù)。

這部分包括了park、unpark等方法。

將一個(gè)線(xiàn)程進(jìn)行掛起是通過(guò)park方法實(shí)現(xiàn)的,調(diào)用 park后,線(xiàn)程將一直阻塞直到超時(shí)或者中斷等條件出現(xiàn)。unpark可以終止一個(gè)掛起的線(xiàn)程,使其恢復(fù)正常。整個(gè)并發(fā)框架中對(duì)線(xiàn)程的掛起操作被封裝在 locksupport類(lèi)中,locksupport類(lèi)中有各種版本pack方法,但最終都調(diào)用了unsafe.park()方法。

七、內(nèi)存屏障。

這部分包括了loadfence、storefence、fullfence等方法。這是在java 8新引入的,用于定義內(nèi)存屏障,避免代碼重排序。

loadfence() 表示該方法之前的所有l(wèi)oad操作在內(nèi)存屏障之前完成。同理storefence()表示該方法之前的所有store操作在內(nèi)存屏障之前完成。fullfence()表示該方法之前的所有l(wèi)oad、store操作在內(nèi)存屏障之前完成。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:http://www.cnblogs.com/pkufork/p/java_unsafe.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品不卡高清在线观看 | 99久久综合九九亚洲 | 九九九九九热 | 青草网在线观看 | 办公室里被迫高h | 亚洲国产精品无圣光一区二区 | 亚洲AV 中文字幕 国产 欧美 | 91麻豆精品激情在线观看最新 | 久久成人精品免费播放 | 男生和女生搞逼逼 | 肉肉小说在线阅读 | 国产视频福利 | 青青青视频免费观看 | 亚洲国产欧美在线人网站 | 国产高清久久 | 欧美综合亚洲图片综合区 | 亚洲天堂中文 | 娇小性色| jk制服蕾丝超短裙流白浆 | 91精品国产色综合久久不卡蜜 | 精品欧美一区二区三区在线观看 | 69热精品视频在线看影院 | 91色香sxmv最网页版新地址 | 艹b视频在线观看 | 亚洲天堂2013 | 国产激情视频网站 | 99在线在线视频免费视频观看 | 国产精品女同久久免费观看 | 日本韩国推理片免费观看网站 | 精品日韩一区 | 日本道高清 | 亚洲成综合人影院在院播放 | 爱情岛论坛亚洲品质自拍视频 | 美女沟厕撒尿全过程高清图片 | 四虎影视在线看免费 720p | 亚洲一二三区久久五月天婷婷 | 日本午夜色 | 国产精品久久久久久久久 | 翁熄性放纵交换300章 | 禁止的爱善良的未删减版hd | 亚洲天堂视频在线播放 |