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