JDK Unsafe類的使用與CAS原子特性

JDK Unsafe類的使用與CAS原子特性

  1. Java.util.concurrent.atomic包,其中包含了大量使用到Unsafe這個類
  2. Java不能直接訪問操作系統的底層,而是通過本地方法來訪問。

Unsafe類提供了硬件級別的原子操作,主要提供了以下功能

  • 內存操作
  • 字段的定位和修改
  • 掛起和恢復
  • CAS操作(樂觀鎖)

內存操作

  • 類提供的3個本地方法allocateMemory、reallocteMemory、freeMemory分別用于分配內存、擴充內存和釋放內存
//和C語言的3個方法對應/**分配內存**/
public native long allocateMemory(long 1);/**擴充內存**/
public native long reallocateMemory(long 1,long l1);/**釋放內存**/
public native void freeMemory(long 1);

字段的定位和修改

  • 可以定位對象字段的內存位置,也可以修改對象的字段值,即使它是私有的

掛起和恢復

  • 將一個線程鼓起是通過park實現的,調用park后,線程會一直阻塞直到超時或者中斷等條件的出現
  • unpark可以終止一個掛起的線程,使其恢復正常
  • 整個并發框架中對于線程的掛起操作被封裝在LockSupport類中,LockSupport類中有各種版本的pack方法,但是最終都調用了Unsafe.park()方法

CAS操作(樂觀鎖)

  • CAS(Compare And Swap)比價并交換
  • CAS操作包含三個操作數? ? 內存位置(V)、預期位置(A)、新值(B)
  • 如果內存位置和預期的原值相匹配,那么處理器就會自動將該位置更新為新值。否則,處理器不做任何操作。無論那種情況,它都會在CAS指令之前返回該位置的值
  • 簡單講就是,我認為V應該包含A值,如果復合預期,就將B放到這個位置,否則,不要改變該位置,只告訴我這個位置現在的值就可以
  • Java并發包(java.util.concurrent)中大量使用了CAS操作,涉及到并發的地方都調用了sun.misc.Unsafe類方法進行CAS操作,在Unsafe中是通過compareAndSwapXXX方法實現的。

底層方法如下

/*
*比較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:用于監聽某些初始化操作,并且將線程進行阻塞,等初始化執行完畢之后,通知主線程繼續工作執行

CyclicBarrier

  • CyclicBarrier:柵欄的概念,多線程的進行阻塞,等待某一個臨界值條件滿足后,同時執行
  • 比如:將每一個線程比作一個跑步運動員,只有所有的運動員都準備好,才能一起賽跑,只要一個人沒有準備好,大家都等等待

Future與Caller回調

  • Future模式:這種模式主要是利用空間換取時間的概念,也就是異步執行(需要開啟一個新的線程)
  • Future模式非常適合在處理耗時很長的業務邏輯時進行使用,可以有效的減少系統的響應時間,提高系統的吞吐量

利用設計模式模擬Future

  • Future模式有點類似于商品訂單
  • 比如網購的時候,挑選商品,提交訂單,付款即可。當訂單處理完成之后,在家里等待商品送貨上門即可。或者形象的說,當我們發送Ajax請求的時候,頁面是異步的進行后臺處理,用戶無需一直等待請求的結果,可以繼續瀏覽或者操作其他內容

Exchanger多線程間數據交換

  • Exchanger用于進行線程間的數據交換,它提供了一個同步點,在這個同步點,兩個線程可以交換彼此的數據
  • 兩個線程通過exchange方法交換數據,如果一個線程先執行excange方法,它會一直等待第二個線程也執行exchange方法
  • 當兩個線程都達到同步點時,這兩個線程就可以交換數據,將本線程生產出來的數據傳遞給對方
  • 使用的場景:1,遺傳算法:遺傳算法里需要選兩個人作為交換對象,這時會交換兩人的數據,并使用交叉規則得出兩個人的交換結果;2,文字校對:A和B同時錄入數據,然后對A和B進行比較,看是否錄入一致,保證數據錄入的正確性;

ForkJoin并行框架

  • Frok/Join框架是Java提供的一個用于并行執行任務的框架,將一個大任務分割成若干個小任務,最終匯總每一個小任務的結果后從而得到大任務的結果
  • ForkJoinTask:使用該框架,需要創建一個ForkJoin任務,它提供在任務中執行fork和join操作的機制。一般情況下,我們不需要直接繼承ForkJoinTask類,只需要繼承他的子類即可
  • RecursiveAction:用于沒有返回結果的任務
  • RecursiveTask:用于有返回結果的任務
  • ForkJoinPool:任務ForkJoinTask需要通過ForkJoinPool來執行

Master-Worker并發組件設計模式

  • Master-Worker模式是常用的并發計算模式,他的核心思想是系統由兩類進程協作工作:Master和aworker進程
  • Master進程負責接收和分配任務,Worker進程負責處理子任務。當各個Worker子進程處理完成之后,會將結果返回給Master,由Master做歸納和總結
  • 其好處是將一個大任務分解成若干個小任務,并行執行,從而提高系統的吞吐量
  • Master-Worker并發組件設計模擬

Semaphore信號量與限流策略

  • Semaphore信號量非常適合并發訪問限制,用于對系統的訪問量進行評估。投入資源太大,資源利用率達不到實際效果,純粹浪費資源;投入資源太小的話,如果一個高峰值的訪問量會壓垮系統

Semaphore相關概念

  • PV(page view)網站的總訪問量,頁面瀏覽量或者點擊量,用戶每刷新一次就會記錄一次
  • UV(unique Visitor)訪問網站的一臺電腦客戶端為一個訪客。一般來講時間上00:00~24:00之內相同ip的客戶端記錄
  • QPS(query per second)即每秒查詢數,qps很大程度上代表了系統業務上的繁忙程度,每次請求的背后,可能對應著多次磁盤I/O,多次網絡請求,多個cpu時間片等。通過qps可以非常直觀了解當前系統業務情況,一旦當前qps超過所設定的預警閥值,可以考慮增加機器對于集群的擴容,防止壓力太大導致宕機,可以根據前期的壓力測試,在結合后期壓力測試得到估值,再結合后期綜合運維情況,估算出閥值
  • RT(response time)請求的響應時間,這個指標非常關鍵,直接說明前段用戶的體驗
  • 當然還涉及cpu、內存、網絡、磁盤等情況,更細節的問題很多,如select、update、delete/ps等數據庫層面的統計。
  • 容量評估:一般來說通過開發、運維、測試、以及業務等相關人員,綜合出系統的一系列閥值,然后我們根據關鍵閥值如qps、rt等,對系統進行有效的變更。
  • 一般來講,我們進行多輪壓力測試以后,可以對系統進行峰值評估,采用所謂的80/20原則,即80%的訪問請求將在20%的時間內達到。這樣我們可以根據系統對應的PV計算出峰值qps。
  • 峰值qps= (總PV × 80%)/ (60 × 60 × 24 × 20%)
  • 然后在將總的峰值qps除以單臺機器所能承受的最高的qps值,就是所需要機器的數量:機器數 = 總的峰值qps / 壓測得出的單機極限qps
  • 當然不排除系統在上線前進行大型促銷活動,或者雙十一、雙十二熱點事件、遭受到DDos攻擊等情況,系統的開發和運維人員急需要了解當前系統運行的狀態和負載情況,一般都會有后臺系統去維護。?? ?

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447343.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447343.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447343.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

寫軟件不是造汽車

寫軟件和做其他事情是不一樣的。當我們制造別的東西的時候——像汽車、玩具、椅子、畫作、甚至包括數字產品如平面圖片和3D模型——我們做出來的成品就是最終的結果。而開發軟件則不是,我們做出來的產品永遠不可能有最終的結果——我們需要向計算機解釋如何根據任意…

線程池核心概述

線程池核心概述 Executors工廠類使用 Executors工廠類底層源碼分析詳解 ThreadPoolExecutor自定義線程池 ThreadPoolExecutor拒絕策略詳解 計算機密集型與IO密集型詳解 如何正確的使用線程池…

網站盈利的10種方式

如果你有自己的網站,而且已經有了不少的流量,你肯定會開始考慮如何通過這個網站來掙一些錢。 在這篇文章中,我會向大家介紹網站最常見的10種盈利方式。 1.按點擊付費廣告 在網站上展示一個按點擊付費的廣告橫幅是最簡單的盈利方式&#xff…

程序員如何創業?

摘要:工作機會減少,讀大學也不是保障。大公司亦不再是構筑職業生涯的安全港灣。透過媒體的鏡頭,創業似乎成了沙漠中唯一的綠洲。然而關于創業,或許少有人給你建議,這里所列出的一些因素都是你可以考慮的。 如果你的年…

Redis數據的類型

Redis一共分為五種基本數據類型:String、Hash、List、Set、Zset. string 內部編碼有三種,raw,embstr,int String 是二進制的。可以存儲序列化對象,圖片,字符串,數值等 set和get方法 &#x…

Redis高級命令與特性以及單點模式的介紹

高級命令 keys * 返回滿足條件的所有key,可以模糊匹配exists 是否存在指定的keypersist 取消過期時間select 選擇數據庫 (0-15,總共16個數據庫)move key index 將當前數據庫的 key 移動到給定的數據庫 db 當中randomkey 隨機返回…

華為副總裁徐家駿離職:年薪千萬工作感悟十二條

從普通的公司職員,到年薪千萬的華為副總裁,再到離開華為轉戰百度,徐家駿的十年從業經歷和經驗可資借鑒,我們從中也可以一窺華為的運作過程。徐家駿是華為數據中心的頭,技術超級牛人,一級部門總監&#xff0…

Redis持久化之RDB和AOF

Redis持久化之RDB和AOF Redis 有兩種持久化方案,RDB (Redis DataBase)和 AOF (Append Only File); RDB 詳解 RDB 是 Redis 默認的持久化方案。在指定的時間間隔內,執行指定次數的寫操作&#…

同為程序員 為什么我的工資最低

我看著工資單上每一個開發團隊成員的薪水,慢慢地我不能保持淡定了。 而當我看到我的工資排名是倒數的時候——靠近最后一名——我不由得倒抽一口冷氣。就像圣誕故事中的那個可愛的小男孩Ralphie ,想買氣槍卻被忽悠會有危險一樣,我也不斷忽悠…

Docker安裝Redis以及配置Redis環境

1,下載Redis鏡像 首先拉取 Redis 鏡像, 這里我選擇的是 redis:alpine 輕量級鏡像版本 docker pull redis:alpine 下載完成后,通過 docker images 查看我們已經下載的鏡像,看看是否已經下載到本地 2,運行 Redis 容器 docker run …

.NET程序性能的基本要領

摘要:本文分享了性能優化的一些建議和思考,比如不要過早優化、好工具很重要、性能的關鍵,在于內存分配等。開發者不要盲目的沒有根據的優化,首先定位和查找到造成產生性能問題的原因點最重要。 【編者按】Bill Chiles&#xff08…

redis.conf配置文件詳解

基本配置 daemonize no #是否以后臺進程啟動databases 16 #創建database的數量(默認選中的是database 0)save 900 1 #刷新快照到硬盤中,必須滿足兩者要求才會觸發,即900秒之后至少1個關鍵字發生變化save 300 10 #必須是300秒之后至少10個關鍵字發生變…

什么原因成就了一位優秀的程序員?

這些年我曾和很多程序員一起工作,他們之中的一些人非常厲害,而另一些人顯得平庸。不久前因為和一些技術非常熟練的程序員工作感覺很愉快,我花了一些時間在考慮我佩服他們什么呢?什么原因讓優秀的程序員那么優秀,糟糕的…

Redis的哨兵模式Sentinel

sentinel功能 redis的sentinel系統用于管理多個redis服務器,該系統主要執行三個任務:監控、提醒、自動故障轉移。 1、監控(Monitoring): Redis Sentinel實時監控主服務器和從服務器運行狀態,并且實現自動…

csdn 到底怎么了?不準轉載?

我轉載了20多文章,很多人閱讀過,但是今天看到閱讀量是0, csdn 到底怎么了? 對用戶這樣?請大家看看是不是這樣?

python3之后版本讀取網頁的內容

import urllib.request url "http://helloworldbook2.com/data/message.txt" #直接通過url來獲取網頁數據 print(第一種) response urllib.request.urlopen(url) code response.getcode() html response.read() mystr html.decode("utf8") response.c…

三十功名塵與土——資深程序員生涯自白

摘要:作者Codist(網名)在程序員崗位上工作了三十多年,在這期間他悟出了一些真理,比如,成功來自對失敗的總結學習;條條大路通羅馬,羅馬并不在乎你用什么方式到達。你在生活中積累了哪…

linux/unix核心設計思想

1) 程序應該小而專一,程序應該盡量的小,且只專注于一件事上,不要開發那些看起來有用但是90%的情況都用不到的特性; 2) 程序不只要考慮性能, 程序的可移植性更重要,shell和perl&…

操作系統環境變量

在 Java中,許多類都是 Iterable ,主要包括所有的 Collection 類(但不包括各種 Maps )。 例如,下面的代碼可以顯示所有的操作系統環境變量: // collections/EnvironmentVariables.java // {VisuallyInspect…

用Unix的設計思想來應對多變的需求

摘要:無論是Unix設計,還是面向對象設計,還是別的什么如SOA,ECB,消息,事件,MVC,網絡七層模型,數據庫設計,等等,他們都在干三件事——解耦&#xff…