久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      JAVA虛擬機(jī)(JVM)詳細(xì)介紹(八)——高效并發(fā)

      JAVA虛擬機(jī)(JVM)詳細(xì)介紹(八)——高效并發(fā)

      內(nèi)存模型

      內(nèi)存模型是在特定的操作協(xié)議下,對(duì)特定的內(nèi)存或高速緩存進(jìn)行讀寫(xiě)訪(fǎng)問(wèn)的過(guò)程抽象。其主要目標(biāo)是定義程序中各個(gè)變量的訪(fǎng)問(wèn)規(guī)則。

      主內(nèi)存和工作內(nèi)存

      JAVA虛擬機(jī)(JVM)詳細(xì)介紹(八)——高效并發(fā)

      所有的變量都存儲(chǔ)在主內(nèi)存中,每條線(xiàn)程還有自己的工作內(nèi)存,其工作內(nèi)存中是被線(xiàn)程使用到的變量的主內(nèi)存副本拷貝,線(xiàn)程對(duì)變量的讀取、賦值等操作都必須在工作內(nèi)存中進(jìn)行,而不能直接讀取主內(nèi)存中的變量。

      內(nèi)存間交互操作

      從主內(nèi)存拷貝到工作內(nèi)存:順序地執(zhí)行read和load操作。
      工作內(nèi)存同步到主內(nèi)存:store和write操作。

      volatile的特性

      Volatile的作用和synchronized相同,但是和synchronized相比,更輕量。其特性主要有如下兩點(diǎn):

      保證此變量對(duì)所有線(xiàn)程的可見(jiàn)性

      啥意思呢?指當(dāng)一個(gè)線(xiàn)程修改了這個(gè)變量的值,新值對(duì)于其他線(xiàn)程來(lái)說(shuō)是立即可知的。而普通變量做不到這一點(diǎn),普通變量的值在線(xiàn)程間傳遞均需要通過(guò)主內(nèi)存來(lái)完成,比如線(xiàn)程A修改了一個(gè)普通變量的值,然后向主內(nèi)存進(jìn)行回寫(xiě),另外一條線(xiàn)程B在線(xiàn)程A回寫(xiě)完成了之后再?gòu)闹鲀?nèi)存進(jìn)行讀取操作,新變量值才會(huì)對(duì)線(xiàn)程B可見(jiàn)。

      禁止指令重排序優(yōu)化

      因?yàn)橹噶钪嘏判驎?huì)干擾程序的并發(fā)執(zhí)行。

      多線(xiàn)程

      為什么需要多線(xiàn)程?

      計(jì)算機(jī)的運(yùn)算速度與它的存儲(chǔ)和通信子系統(tǒng)速度的差距太大,大量的時(shí)間都花費(fèi)在磁盤(pán)I/O、網(wǎng)絡(luò)通信、數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)上了。使用多線(xiàn)程能更好地利用cpu。

      有哪些并發(fā)應(yīng)用場(chǎng)景?

      充分利用計(jì)算機(jī)處理器

      一個(gè)服務(wù)端同時(shí)對(duì)多個(gè)客戶(hù)端提供服務(wù)

      如何使處理器內(nèi)部的運(yùn)算單元被充分利用?

      加入一層高速緩存

      將運(yùn)算需要使用到的數(shù)據(jù)復(fù)制到緩存中,讓運(yùn)算能快速進(jìn)行。當(dāng)運(yùn)算結(jié)束后再?gòu)木彺嫱交貎?nèi)存中,這樣處理器就無(wú)須等待緩慢的內(nèi)存讀寫(xiě)了。不過(guò)這個(gè)要考慮一個(gè)問(wèn)題:怎么保證緩存的一致性。

      JAVA虛擬機(jī)(JVM)詳細(xì)介紹(八)——高效并發(fā)

      對(duì)輸入代碼進(jìn)行亂序執(zhí)行優(yōu)化

      線(xiàn)程的實(shí)現(xiàn)方式

      使用內(nèi)核線(xiàn)程實(shí)現(xiàn)

      內(nèi)核線(xiàn)程就是直接由操作系統(tǒng)內(nèi)核支持的線(xiàn)程。

      使用用戶(hù)線(xiàn)程實(shí)現(xiàn)

      用戶(hù)線(xiàn)程的建立、同步、銷(xiāo)毀和調(diào)度完全在用戶(hù)態(tài)中完成,不需要內(nèi)核的幫助,內(nèi)核也感知不到線(xiàn)程存在的實(shí)現(xiàn)。這種實(shí)現(xiàn)方式使用較少。

      使用用戶(hù)線(xiàn)程加輕量級(jí)進(jìn)行混合實(shí)現(xiàn)

      合并到一起

      線(xiàn)程調(diào)度

      線(xiàn)程調(diào)度是指系統(tǒng)為線(xiàn)程分配處理器使用權(quán)的過(guò)程。主要分為兩種:協(xié)同式和搶占式。

      協(xié)同式

      線(xiàn)程的執(zhí)行時(shí)間由線(xiàn)程本身來(lái)控制,線(xiàn)程把自己的工作執(zhí)行完了,會(huì)主動(dòng)通知系統(tǒng)切換到另外一個(gè)線(xiàn)程上。
      其優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,而且沒(méi)有線(xiàn)程同步的問(wèn)題。缺點(diǎn)是如果一個(gè)線(xiàn)程編寫(xiě)有問(wèn)題,一直不告訴系統(tǒng)進(jìn)行線(xiàn)程切換,那程序就會(huì)一直阻塞在那里,容易導(dǎo)致系統(tǒng)崩潰。

      搶占式

      線(xiàn)程將由系統(tǒng)來(lái)分配執(zhí)行時(shí)間,線(xiàn)程切換不由本身來(lái)決定。java使用的線(xiàn)程調(diào)度方式就是這種。

      線(xiàn)程安全

      當(dāng)多個(gè)線(xiàn)程訪(fǎng)問(wèn)一個(gè)對(duì)象時(shí),如果不考慮這個(gè)線(xiàn)程在運(yùn)行時(shí)環(huán)境下的調(diào)度和交替執(zhí)行,也不需要進(jìn)行額外的同步,或者在調(diào)用方進(jìn)行任何其它的協(xié)調(diào)操作,調(diào)用這個(gè)對(duì)象的行為都可以獲得正確的結(jié)果,那這個(gè)對(duì)象就是安全的。

      共享數(shù)據(jù)的分類(lèi)

      不可變

      不可變的共享數(shù)據(jù)是用final修飾的數(shù)據(jù),其一定是線(xiàn)程安全的。如果共享數(shù)據(jù)是一個(gè)基本類(lèi)型變量,那么只要在定義的時(shí)候使用final關(guān)鍵字即可。

      如果共享數(shù)據(jù)是一個(gè)對(duì)象,那就需要對(duì)象的行為不會(huì)對(duì)其狀態(tài)產(chǎn)生影響,可以將對(duì)象中帶有狀態(tài)的變量都聲明為final。比如String類(lèi)就是一個(gè)不可變類(lèi)

      絕對(duì)線(xiàn)程安全

      在Java API中標(biāo)注自己是線(xiàn)程安全的類(lèi),大多數(shù)都不是絕對(duì)的線(xiàn)程安全。比如Vector是一個(gè)線(xiàn)程安全的集合,它的所有的方法都被修飾成同步,但是在多線(xiàn)程的環(huán)境中,它依舊不是同步的。

      相對(duì)線(xiàn)程安全

      相對(duì)線(xiàn)程安全就是我們通常意義上所說(shuō)的線(xiàn)程安全,它只能保證對(duì)這個(gè)對(duì)象單獨(dú)操作是線(xiàn)程安全的。但是對(duì)于一些特定順序的連續(xù)調(diào)用,就可能需要在調(diào)用端使用額外的同步手段來(lái)保證調(diào)用的正確性。
      大部分的線(xiàn)程安全類(lèi)都屬于這種類(lèi)型。

      線(xiàn)程兼容

      對(duì)象本身不是線(xiàn)性安全的,但可以通過(guò)在調(diào)用端正確地使用同步手段來(lái)保證對(duì)象在并發(fā)環(huán)境中可以安全的使用。大部分的不是線(xiàn)程安全的類(lèi),都屬于這種類(lèi)型。

      線(xiàn)程對(duì)立

      無(wú)論怎樣,都不能在多線(xiàn)程環(huán)境中并發(fā)使用,如System.setIn()、System.SetOut()。一個(gè)對(duì)輸入進(jìn)行修改,一個(gè)對(duì)輸出進(jìn)行修改,兩者是不能“交替”進(jìn)行的。

      實(shí)現(xiàn)方法

      方式一:互斥同步——悲觀并發(fā)策略

      (1)synchronized

      其原理是:這個(gè)關(guān)鍵字在經(jīng)過(guò)編譯后,會(huì)在同步塊的前后分別形成monitorenter和monitorexit這兩個(gè)字節(jié)碼指令。當(dāng)執(zhí)行monitorenter指令時(shí),程序會(huì)嘗試獲取對(duì)象的鎖,如果能獲取到,則把鎖的計(jì)數(shù)器+1,相應(yīng)的,在執(zhí)行monitorexit時(shí),會(huì)將鎖計(jì)數(shù)器-1。當(dāng)計(jì)數(shù)器為0時(shí),鎖就被釋放。

      其特點(diǎn)是:對(duì)同一條線(xiàn)程來(lái)說(shuō)是可重入的;同步塊在已進(jìn)入的線(xiàn)程執(zhí)行完之前,會(huì)阻塞后面的其他線(xiàn)程進(jìn)入。

      其選用場(chǎng)景是:在確實(shí)必要的情況下才使用此,因?yàn)槠涫侵亓考?jí)的。

      (2)ReentrantLock

      此重入鎖是java.util.concurrent(JUC)包下的類(lèi)。其高級(jí)特性有:等待可中斷、可實(shí)現(xiàn)公平鎖、鎖可以綁定多個(gè)條件。

      方式二:非阻塞同步——樂(lè)觀并發(fā)策略

      先進(jìn)行操作,如果沒(méi)有其它線(xiàn)程爭(zhēng)用共享數(shù)據(jù),那操作就是成功了;如果共享數(shù)據(jù)有爭(zhēng)用,產(chǎn)生了沖突,那就再采取其它的補(bǔ)償措施。

      方式三:無(wú)同步方案

      如果一個(gè)方法本來(lái)就不涉及共享數(shù)據(jù),那就沒(méi)有必要進(jìn)行同步措施。比如可重復(fù)代碼和線(xiàn)程本地存儲(chǔ)。

      (1)可重入代碼

      如果一個(gè)方法,它的返回結(jié)果是可預(yù)測(cè)的,只要輸入了相同的數(shù)據(jù),就都能返回相同的結(jié)果,那它就滿(mǎn)足可重入的要求。

      (2)線(xiàn)程本地存儲(chǔ)

      如果一段代碼中所需要的數(shù)據(jù)必須與其它代碼共享,而且這些共享數(shù)據(jù)的代碼在同一個(gè)線(xiàn)程中執(zhí)行,如此,我們可以把共享數(shù)據(jù)的可見(jiàn)范圍限制在一個(gè)線(xiàn)程中,這樣,就不用同步也能保證線(xiàn)程之間不出現(xiàn)數(shù)據(jù)爭(zhēng)用問(wèn)題。

      鎖優(yōu)化

      適應(yīng)性自旋

      因?yàn)樽枞蛘邌拘岩粋€(gè)JAVA的線(xiàn)程需要操作系統(tǒng)切換CPU狀態(tài)來(lái)完成,這種狀態(tài)的轉(zhuǎn)換需要耗費(fèi)處理器時(shí)間。如果同步代碼塊中的內(nèi)容過(guò)于簡(jiǎn)單,很可能導(dǎo)致?tīng)顟B(tài)轉(zhuǎn)換消耗的時(shí)間比用戶(hù)代碼執(zhí)行的時(shí)間還要長(zhǎng)。

      為了解決這個(gè)問(wèn)題,我們可以讓后面請(qǐng)求鎖的線(xiàn)程“稍等一下”,執(zhí)行一個(gè)忙循環(huán),進(jìn)行自旋。此時(shí)沒(méi)有放棄處理器的執(zhí)行時(shí)間。如果自旋超過(guò)了限定的次數(shù),仍然沒(méi)有成功獲得鎖,那就會(huì)使用傳統(tǒng)的方式去掛起線(xiàn)程了。

      那什么叫做適應(yīng)性自旋呢?

      就是在同一個(gè)鎖對(duì)象上,如果自旋等待剛剛成功獲得過(guò)鎖,那虛擬機(jī)就會(huì)認(rèn)為這次自旋獲得鎖的概率挺大,就會(huì)允許其自旋等待持續(xù)相對(duì)更長(zhǎng)的時(shí)間。相反,如果自旋很少成功獲得過(guò)鎖,則可能省略掉自旋過(guò)程。

      鎖消除

      指虛擬機(jī)即時(shí)編譯器在運(yùn)行時(shí),對(duì)一些代碼上要求同步,但是被檢測(cè)到不可能存在共享數(shù)據(jù)競(jìng)爭(zhēng)的鎖進(jìn)行消除。

      鎖粗化

      如果一系列的連續(xù)操作都對(duì)同一個(gè)對(duì)象反復(fù)加鎖和解鎖,甚至加鎖操作是出現(xiàn)在循環(huán)體中的,那即使沒(méi)有線(xiàn)程競(jìng)爭(zhēng),頻繁地進(jìn)行互斥同步操作也會(huì)導(dǎo)致不必要的性能損耗。
      如果虛擬機(jī)探測(cè)到一串零碎的操作都對(duì)同一個(gè)對(duì)象加鎖,將會(huì)把加鎖同步的范圍粗化到整個(gè)操作序列的外部,這樣只需要加鎖一次就夠了。

      輕量級(jí)鎖

      在沒(méi)有多線(xiàn)程競(jìng)爭(zhēng)的前提下,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能損耗。
      適用場(chǎng)景:無(wú)實(shí)際競(jìng)爭(zhēng),多個(gè)線(xiàn)程交替使用鎖;允許短時(shí)間的鎖競(jìng)爭(zhēng)。

      偏向鎖

      偏向鎖用于減少無(wú)競(jìng)爭(zhēng)且只有一個(gè)線(xiàn)程使用鎖的情況下,使用輕量級(jí)鎖產(chǎn)生的性能消耗。輕量級(jí)鎖每次申請(qǐng)、釋放鎖都至少需要一次CAS,但偏向鎖只有初始化時(shí)需要一次CAS。
      適用場(chǎng)景:無(wú)實(shí)際競(jìng)爭(zhēng),且將來(lái)只有第一個(gè)申請(qǐng)鎖的線(xiàn)程會(huì)使用鎖。

      以上是關(guān)于JAVA虛擬機(jī)中高效并發(fā)的詳細(xì)介紹,

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)