久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放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. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

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

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

      內(nèi)存模型

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

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

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

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

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

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

      volatile的特性

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

      保證此變量對所有線程的可見性

      啥意思呢?指當一個線程修改了這個變量的值,新值對于其他線程來說是立即可知的。而普通變量做不到這一點,普通變量的值在線程間傳遞均需要通過主內(nèi)存來完成,比如線程A修改了一個普通變量的值,然后向主內(nèi)存進行回寫,另外一條線程B在線程A回寫完成了之后再從主內(nèi)存進行讀取操作,新變量值才會對線程B可見。

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

      因為指令重排序會干擾程序的并發(fā)執(zhí)行。

      多線程

      為什么需要多線程?

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

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

      充分利用計算機處理器

      一個服務(wù)端同時對多個客戶端提供服務(wù)

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

      加入一層高速緩存

      將運算需要使用到的數(shù)據(jù)復制到緩存中,讓運算能快速進行。當運算結(jié)束后再從緩存同步回內(nèi)存中,這樣處理器就無須等待緩慢的內(nèi)存讀寫了。不過這個要考慮一個問題:怎么保證緩存的一致性。

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

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

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

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

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

      使用用戶線程實現(xiàn)

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

      使用用戶線程加輕量級進行混合實現(xiàn)

      合并到一起

      線程調(diào)度

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

      協(xié)同式

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

      搶占式

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

      線程安全

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

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

      不可變

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

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

      絕對線程安全

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

      相對線程安全

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

      線程兼容

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

      線程對立

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

      實現(xiàn)方法

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

      (1)synchronized

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

      其特點是:對同一條線程來說是可重入的;同步塊在已進入的線程執(zhí)行完之前,會阻塞后面的其他線程進入。

      其選用場景是:在確實必要的情況下才使用此,因為其是重量級的。

      (2)ReentrantLock

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

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

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

      方式三:無同步方案

      如果一個方法本來就不涉及共享數(shù)據(jù),那就沒有必要進行同步措施。比如可重復代碼和線程本地存儲。

      (1)可重入代碼

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

      (2)線程本地存儲

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

      鎖優(yōu)化

      適應(yīng)性自旋

      因為阻塞或者喚醒一個JAVA的線程需要操作系統(tǒng)切換CPU狀態(tài)來完成,這種狀態(tài)的轉(zhuǎn)換需要耗費處理器時間。如果同步代碼塊中的內(nèi)容過于簡單,很可能導致狀態(tài)轉(zhuǎn)換消耗的時間比用戶代碼執(zhí)行的時間還要長。

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

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

      就是在同一個鎖對象上,如果自旋等待剛剛成功獲得過鎖,那虛擬機就會認為這次自旋獲得鎖的概率挺大,就會允許其自旋等待持續(xù)相對更長的時間。相反,如果自旋很少成功獲得過鎖,則可能省略掉自旋過程。

      鎖消除

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

      鎖粗化

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

      輕量級鎖

      在沒有多線程競爭的前提下,減少傳統(tǒng)的重量級鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能損耗。
      適用場景:無實際競爭,多個線程交替使用鎖;允許短時間的鎖競爭。

      偏向鎖

      偏向鎖用于減少無競爭且只有一個線程使用鎖的情況下,使用輕量級鎖產(chǎn)生的性能消耗。輕量級鎖每次申請、釋放鎖都至少需要一次CAS,但偏向鎖只有初始化時需要一次CAS。
      適用場景:無實際競爭,且將來只有第一個申請鎖的線程會使用鎖。

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

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