JDK Unsafe类的使用与CAS原子特性
生活随笔
收集整理的這篇文章主要介紹了
JDK Unsafe类的使用与CAS原子特性
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
JDK Unsafe類(lèi)的使用與CAS原子特性
Unsafe類(lèi)提供了硬件級(jí)別的原子操作,主要提供了以下功能
- 內(nèi)存操作
- 字段的定位和修改
- 掛起和恢復(fù)
- CAS操作(樂(lè)觀鎖)
內(nèi)存操作
- 類(lèi)提供的3個(gè)本地方法allocateMemory、reallocteMemory、freeMemory分別用于分配內(nèi)存、擴(kuò)充內(nèi)存和釋放內(nèi)存
字段的定位和修改
- 可以定位對(duì)象字段的內(nèi)存位置,也可以修改對(duì)象的字段值,即使它是私有的
掛起和恢復(fù)
- 將一個(gè)線程鼓起是通過(guò)park實(shí)現(xiàn)的,調(diào)用park后,線程會(huì)一直阻塞直到超時(shí)或者中斷等條件的出現(xiàn)
- unpark可以終止一個(gè)掛起的線程,使其恢復(fù)正常
- 整個(gè)并發(fā)框架中對(duì)于線程的掛起操作被封裝在LockSupport類(lèi)中,LockSupport類(lèi)中有各種版本的pack方法,但是最終都調(diào)用了Unsafe.park()方法
CAS操作(樂(lè)觀鎖)
- CAS(Compare And Swap)比價(jià)并交換
- CAS操作包含三個(gè)操作數(shù)? ? 內(nèi)存位置(V)、預(yù)期位置(A)、新值(B)
- 如果內(nèi)存位置和預(yù)期的原值相匹配,那么處理器就會(huì)自動(dòng)將該位置更新為新值。否則,處理器不做任何操作。無(wú)論那種情況,它都會(huì)在CAS指令之前返回該位置的值
- 簡(jiǎn)單講就是,我認(rèn)為V應(yīng)該包含A值,如果復(fù)合預(yù)期,就將B放到這個(gè)位置,否則,不要改變?cè)撐恢?#xff0c;只告訴我這個(gè)位置現(xiàn)在的值就可以
- Java并發(fā)包(java.util.concurrent)中大量使用了CAS操作,涉及到并發(fā)的地方都調(diào)用了sun.misc.Unsafe類(lèi)方法進(jìn)行CAS操作,在Unsafe中是通過(guò)compareAndSwapXXX方法實(shí)現(xiàn)的。
底層方法如下
/* *比較obj的offset處內(nèi)存位置中的值和期望的值,如果相同則更新,此更新是不可中斷的*@Param obj需要更新的操作 *@Param offset obj中整型的field偏移量 *@Param expect 希望field中存在的值 *@Param update 如果期望值except與field當(dāng)前值相同,設(shè)置field這個(gè)值為新值 *@return 如果field的值將被改變則返回true */ public native boolean compareAndSwapInt(Object obj,long offset,int expect,int update)CountDownLatch
-
CountDownLatch:用于監(jiān)聽(tīng)某些初始化操作,并且將線程進(jìn)行阻塞,等初始化執(zhí)行完畢之后,通知主線程繼續(xù)工作執(zhí)行
CyclicBarrier
- CyclicBarrier:柵欄的概念,多線程的進(jìn)行阻塞,等待某一個(gè)臨界值條件滿(mǎn)足后,同時(shí)執(zhí)行
- 比如:將每一個(gè)線程比作一個(gè)跑步運(yùn)動(dòng)員,只有所有的運(yùn)動(dòng)員都準(zhǔn)備好,才能一起賽跑,只要一個(gè)人沒(méi)有準(zhǔn)備好,大家都等等待
Future與Caller回調(diào)
- Future模式:這種模式主要是利用空間換取時(shí)間的概念,也就是異步執(zhí)行(需要開(kāi)啟一個(gè)新的線程)
- Future模式非常適合在處理耗時(shí)很長(zhǎng)的業(yè)務(wù)邏輯時(shí)進(jìn)行使用,可以有效的減少系統(tǒng)的響應(yīng)時(shí)間,提高系統(tǒng)的吞吐量
利用設(shè)計(jì)模式模擬Future
- Future模式有點(diǎn)類(lèi)似于商品訂單
- 比如網(wǎng)購(gòu)的時(shí)候,挑選商品,提交訂單,付款即可。當(dāng)訂單處理完成之后,在家里等待商品送貨上門(mén)即可。或者形象的說(shuō),當(dāng)我們發(fā)送Ajax請(qǐng)求的時(shí)候,頁(yè)面是異步的進(jìn)行后臺(tái)處理,用戶(hù)無(wú)需一直等待請(qǐng)求的結(jié)果,可以繼續(xù)瀏覽或者操作其他內(nèi)容
Exchanger多線程間數(shù)據(jù)交換
- Exchanger用于進(jìn)行線程間的數(shù)據(jù)交換,它提供了一個(gè)同步點(diǎn),在這個(gè)同步點(diǎn),兩個(gè)線程可以交換彼此的數(shù)據(jù)
- 兩個(gè)線程通過(guò)exchange方法交換數(shù)據(jù),如果一個(gè)線程先執(zhí)行excange方法,它會(huì)一直等待第二個(gè)線程也執(zhí)行exchange方法
- 當(dāng)兩個(gè)線程都達(dá)到同步點(diǎn)時(shí),這兩個(gè)線程就可以交換數(shù)據(jù),將本線程生產(chǎn)出來(lái)的數(shù)據(jù)傳遞給對(duì)方
- 使用的場(chǎng)景:1,遺傳算法:遺傳算法里需要選兩個(gè)人作為交換對(duì)象,這時(shí)會(huì)交換兩人的數(shù)據(jù),并使用交叉規(guī)則得出兩個(gè)人的交換結(jié)果;2,文字校對(duì):A和B同時(shí)錄入數(shù)據(jù),然后對(duì)A和B進(jìn)行比較,看是否錄入一致,保證數(shù)據(jù)錄入的正確性;
ForkJoin并行框架
- Frok/Join框架是Java提供的一個(gè)用于并行執(zhí)行任務(wù)的框架,將一個(gè)大任務(wù)分割成若干個(gè)小任務(wù),最終匯總每一個(gè)小任務(wù)的結(jié)果后從而得到大任務(wù)的結(jié)果
- ForkJoinTask:使用該框架,需要?jiǎng)?chuàng)建一個(gè)ForkJoin任務(wù),它提供在任務(wù)中執(zhí)行fork和join操作的機(jī)制。一般情況下,我們不需要直接繼承ForkJoinTask類(lèi),只需要繼承他的子類(lèi)即可
- RecursiveAction:用于沒(méi)有返回結(jié)果的任務(wù)
- RecursiveTask:用于有返回結(jié)果的任務(wù)
- ForkJoinPool:任務(wù)ForkJoinTask需要通過(guò)ForkJoinPool來(lái)執(zhí)行
Master-Worker并發(fā)組件設(shè)計(jì)模式
- Master-Worker模式是常用的并發(fā)計(jì)算模式,他的核心思想是系統(tǒng)由兩類(lèi)進(jìn)程協(xié)作工作:Master和aworker進(jìn)程
- Master進(jìn)程負(fù)責(zé)接收和分配任務(wù),Worker進(jìn)程負(fù)責(zé)處理子任務(wù)。當(dāng)各個(gè)Worker子進(jìn)程處理完成之后,會(huì)將結(jié)果返回給Master,由Master做歸納和總結(jié)
- 其好處是將一個(gè)大任務(wù)分解成若干個(gè)小任務(wù),并行執(zhí)行,從而提高系統(tǒng)的吞吐量
-
Master-Worker并發(fā)組件設(shè)計(jì)模擬
Semaphore信號(hào)量與限流策略
- Semaphore信號(hào)量非常適合并發(fā)訪問(wèn)限制,用于對(duì)系統(tǒng)的訪問(wèn)量進(jìn)行評(píng)估。投入資源太大,資源利用率達(dá)不到實(shí)際效果,純粹浪費(fèi)資源;投入資源太小的話(huà),如果一個(gè)高峰值的訪問(wèn)量會(huì)壓垮系統(tǒng)
Semaphore相關(guān)概念
- PV(page view)網(wǎng)站的總訪問(wèn)量,頁(yè)面瀏覽量或者點(diǎn)擊量,用戶(hù)每刷新一次就會(huì)記錄一次
- UV(unique Visitor)訪問(wèn)網(wǎng)站的一臺(tái)電腦客戶(hù)端為一個(gè)訪客。一般來(lái)講時(shí)間上00:00~24:00之內(nèi)相同ip的客戶(hù)端記錄
- QPS(query per second)即每秒查詢(xún)數(shù),qps很大程度上代表了系統(tǒng)業(yè)務(wù)上的繁忙程度,每次請(qǐng)求的背后,可能對(duì)應(yīng)著多次磁盤(pán)I/O,多次網(wǎng)絡(luò)請(qǐng)求,多個(gè)cpu時(shí)間片等。通過(guò)qps可以非常直觀了解當(dāng)前系統(tǒng)業(yè)務(wù)情況,一旦當(dāng)前qps超過(guò)所設(shè)定的預(yù)警閥值,可以考慮增加機(jī)器對(duì)于集群的擴(kuò)容,防止壓力太大導(dǎo)致宕機(jī),可以根據(jù)前期的壓力測(cè)試,在結(jié)合后期壓力測(cè)試得到估值,再結(jié)合后期綜合運(yùn)維情況,估算出閥值
- RT(response time)請(qǐng)求的響應(yīng)時(shí)間,這個(gè)指標(biāo)非常關(guān)鍵,直接說(shuō)明前段用戶(hù)的體驗(yàn)
- 當(dāng)然還涉及cpu、內(nèi)存、網(wǎng)絡(luò)、磁盤(pán)等情況,更細(xì)節(jié)的問(wèn)題很多,如select、update、delete/ps等數(shù)據(jù)庫(kù)層面的統(tǒng)計(jì)。
- 容量評(píng)估:一般來(lái)說(shuō)通過(guò)開(kāi)發(fā)、運(yùn)維、測(cè)試、以及業(yè)務(wù)等相關(guān)人員,綜合出系統(tǒng)的一系列閥值,然后我們根據(jù)關(guān)鍵閥值如qps、rt等,對(duì)系統(tǒng)進(jìn)行有效的變更。
- 一般來(lái)講,我們進(jìn)行多輪壓力測(cè)試以后,可以對(duì)系統(tǒng)進(jìn)行峰值評(píng)估,采用所謂的80/20原則,即80%的訪問(wèn)請(qǐng)求將在20%的時(shí)間內(nèi)達(dá)到。這樣我們可以根據(jù)系統(tǒng)對(duì)應(yīng)的PV計(jì)算出峰值qps。
- 峰值qps= (總PV × 80%)/ (60 × 60 × 24 × 20%)
- 然后在將總的峰值qps除以單臺(tái)機(jī)器所能承受的最高的qps值,就是所需要機(jī)器的數(shù)量:機(jī)器數(shù) = 總的峰值qps / 壓測(cè)得出的單機(jī)極限qps
- 當(dāng)然不排除系統(tǒng)在上線前進(jìn)行大型促銷(xiāo)活動(dòng),或者雙十一、雙十二熱點(diǎn)事件、遭受到DDos攻擊等情況,系統(tǒng)的開(kāi)發(fā)和運(yùn)維人員急需要了解當(dāng)前系統(tǒng)運(yùn)行的狀態(tài)和負(fù)載情況,一般都會(huì)有后臺(tái)系統(tǒng)去維護(hù)。?? ?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的JDK Unsafe类的使用与CAS原子特性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《原神》北斗技能解析及装备选择推荐
- 下一篇: 算法入门篇三 详解桶排序和整理排序知识