自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

搞懂這幾個鎖用法,多線程就懂一半了

開發(fā) 后端
synchronized機制是給共享資源上鎖,只有拿到鎖的線程才可以訪問共享資源,這樣就可以強制使得對共享資源的訪問都是順序的。

 [[315805]]

0x01:synchronized

在Java中synchronized關(guān)鍵字被常用于維護(hù)數(shù)據(jù)一致性。

synchronized機制是給共享資源上鎖,只有拿到鎖的線程才可以訪問共享資源,這樣就可以強制使得對共享資源的訪問都是順序的。

Java開發(fā)人員都認(rèn)識synchronized,使用它來實現(xiàn)多線程的同步操作是非常簡單的,只要在需要同步的對方的方法、類或代碼塊中加入該關(guān)鍵字,它能夠保證在同一個時刻最多只有一個線程執(zhí)行同一個對象的同步代碼,可保證修飾的代碼在執(zhí)行過程中不會被其他線程干擾。使用synchronized修飾的代碼具有原子性和可見性,在需要進(jìn)程同步的程序中使用的頻率非常高,可以滿足一般的進(jìn)程同步要求。

synchronized(obj){//方法…….}

synchronized實現(xiàn)的機理依賴于軟件層面上的JVM,因此其性能會隨著Java版本的不斷升級而提高。

到了Java1.6,synchronized進(jìn)行了很多的優(yōu)化,有適應(yīng)自旋、鎖消除、鎖粗化、輕量級鎖及偏向鎖等,效率有了本質(zhì)上的提高。在之后推出的Java1.7與1.8中,均對該關(guān)鍵字的實現(xiàn)機理做了優(yōu)化。

需要說明的是,當(dāng)線程通過synchronized等待鎖時是不能被Thread.interrupt()中斷的,因此程序設(shè)計時必須檢查確保合理,否則可能會造成線程死鎖的尷尬境地。

最后,盡管Java實現(xiàn)的鎖機制有很多種,并且有些鎖機制性能也比synchronized高,但還是強烈推薦在多線程應(yīng)用程序中使用該關(guān)鍵字,因為實現(xiàn)方便,后續(xù)工作由JVM來完成,可靠性高。只有在確定鎖機制是當(dāng)前多線程程序的性能瓶頸時,才考慮使用其他機制,如ReentrantLock等。

0x02:ReentrantLock

可重入鎖,顧名思義,這個鎖可以被線程多次重復(fù)進(jìn)入進(jìn)行獲取操作。

ReentantLock繼承接口Lock并實現(xiàn)了接口中定義的方法,除了能完成synchronized所能完成的所有工作外,還提供了諸如可響應(yīng)中斷鎖、可輪詢鎖請求、定時鎖等避免多線程死鎖的方法。

Lock實現(xiàn)的機理依賴于特殊的CPU指定,可以認(rèn)為不受JVM的約束,并可以通過其他語言平臺來完成底層的實現(xiàn)。在并發(fā)量較小的多線程應(yīng)用程序中,ReentrantLock與synchronized性能相差無幾,但在高并發(fā)量的條件下,synchronized性能會迅速下降幾十倍,而ReentrantLock的性能卻能依然維持一個水準(zhǔn)。

因此我們建議在高并發(fā)量情況下使用ReentrantLock。

ReentrantLock引入兩個概念:公平鎖與非公平鎖。

公平鎖指的是鎖的分配機制是公平的,通常先對鎖提出獲取請求的線程會先被分配到鎖。反之,JVM按隨機、就近原則分配鎖的機制則稱為不公平鎖。

ReentrantLock在構(gòu)造函數(shù)中提供了是否公平鎖的初始化方式,默認(rèn)為非公平鎖。這是因為,非公平鎖實際執(zhí)行的效率要遠(yuǎn)遠(yuǎn)超出公平鎖,除非程序有特殊需要,否則最常用非公平鎖的分配機制。

ReentrantLock通過方法lock()與unlock()來進(jìn)行加鎖與解鎖操作,與synchronized會被JVM自動解鎖機制不同,ReentrantLock加鎖后需要手動進(jìn)行解鎖。為了避免程序出現(xiàn)異常而無法正常解鎖的情況,使用ReentrantLock必須在finally控制塊中進(jìn)行解鎖操作。通常使用方式如下所示:

Locklock=newReentrantLock();try{lock.lock();//…進(jìn)行任務(wù)操作5}finally{lock.unlock();}

0x03:Semaphore

上述兩種鎖機制類型都是“互斥鎖”,學(xué)過操作系統(tǒng)的都知道,互斥是進(jìn)程同步關(guān)系的一種特殊情況,相當(dāng)于只存在一個臨界資源,因此同時最多只能給一個線程提供服務(wù)。但是,在實際復(fù)雜的多線程應(yīng)用程序中,可能存在多個臨界資源,這時候我們可以借助Semaphore信號量來完成多個臨界資源的訪問。

Semaphore基本能完成ReentrantLock的所有工作,使用方法也與之類似,通過acquire()與release()方法來獲得和釋放臨界資源。

經(jīng)實測,Semaphone.acquire()方法默認(rèn)為可響應(yīng)中斷鎖,與ReentrantLock.lockInterruptibly()作用效果一致,也就是說在等待臨界資源的過程中可以被Thread.interrupt()方法中斷。

此外,Semaphore也實現(xiàn)了可輪詢的鎖請求與定時鎖的功能,除了方法名tryAcquire與tryLock不同,其使用方法與ReentrantLock幾乎一致。Semaphore也提供了公平與非公平鎖的機制,也可在構(gòu)造函數(shù)中進(jìn)行設(shè)定。

Semaphore的鎖釋放操作也由手動進(jìn)行,因此與ReentrantLock一樣,為避免線程因拋出異常而無法正常釋放鎖的情況發(fā)生,釋放鎖的操作也必須在finally代碼塊中完成。

用于獲取權(quán)限的acquire(),其底層實現(xiàn)與CountDownLatch.countdown()類似;用于釋放權(quán)限的release(),其底層實現(xiàn)與acquire()是一個互逆的過程。

0x04:CountDownLatch

CountDownLatch是一個計數(shù)器閉鎖,通過它可以完成類似于阻塞當(dāng)前線程的功能,即:一個線程或多個線程一直等待,直到其他線程執(zhí)行的操作完成。CountDownLatch用一個給定的計數(shù)器來初始化,該計數(shù)器的操作是原子操作,即同時只能有一個線程去操作該計數(shù)器。調(diào)用該類await方法的線程會一直處于阻塞狀態(tài),直到其他線程調(diào)用countDown方法使當(dāng)前計數(shù)器的值變?yōu)榱?,每次調(diào)用countDown計數(shù)器的值減1。當(dāng)計數(shù)器值減至零時,所有因調(diào)用await()方法而處于等待狀態(tài)的線程就會繼續(xù)往下執(zhí)行。這種現(xiàn)象只會出現(xiàn)一次,因為計數(shù)器不能被重置,如果業(yè)務(wù)上需要一個可以重置計數(shù)次數(shù)的版本,可以考慮使用CycliBarrier。

在某些業(yè)務(wù)場景中,程序執(zhí)行需要等待某個條件完成后才能繼續(xù)執(zhí)行后續(xù)的操作;典型的應(yīng)用如并行計算,當(dāng)某個處理的運算量很大時,可以將該運算任務(wù)拆分成多個子任務(wù),等待所有的子任務(wù)都完成之后,父任務(wù)再拿到所有子任務(wù)的運算結(jié)果進(jìn)行匯總。

0x05:CyclicBarrier

CyclicBarrier也是一個同步輔助類,它允許一組線程相互等待,直到到達(dá)某個公共屏障點(common barrier point)。通過它可以完成多個線程之間相互等待,只有當(dāng)每個線程都準(zhǔn)備就緒后,才能各自繼續(xù)往下執(zhí)行后面的操作。類似于CountDownLatch,它也是通過計數(shù)器來實現(xiàn)的。當(dāng)某個線程調(diào)用await方法時,該線程進(jìn)入等待狀態(tài),且計數(shù)器加1,當(dāng)計數(shù)器的值達(dá)到設(shè)置的初始值時,所有因調(diào)用await進(jìn)入等待狀態(tài)的線程被喚醒,繼續(xù)執(zhí)行后續(xù)操作。因為CycliBarrier在釋放等待線程后可以重用,所以稱為循環(huán)barrier。CycliBarrier支持一個可選的Runnable,在計數(shù)器的值到達(dá)設(shè)定值后(但在釋放所有線程之前),該Runnable運行一次,注,Runnable在每個屏障點只運行一個。

使用場景類似于CountDownLatch與CountDownLatch的區(qū)別

  • CountDownLatch主要是實現(xiàn)了1個或N個線程需要等待其他線程完成某項操作之后才能繼續(xù)往下執(zhí)行操作,描述的是1個線程或N個線程等待其他線程的關(guān)系。CyclicBarrier主要是實現(xiàn)了多個線程之間相互等待,直到所有的線程都滿足了條件之后各自才能繼續(xù)執(zhí)行后續(xù)的操作,描述的多個線程內(nèi)部相互等待的關(guān)系。
  • CountDownLatch是一次性的,而CyclicBarrier則可以被重置而重復(fù)使用。

 

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2015-07-27 10:24:01

蘋果中國

2013-02-25 10:11:35

4GLTE商用網(wǎng)絡(luò)

2020-12-04 10:11:26

Unsafejava并發(fā)包

2021-09-26 16:08:24

手機電池充電

2025-02-27 07:00:00

解構(gòu)賦值代碼JavaScript

2020-09-21 08:33:12

線程池調(diào)度Thread Pool

2019-10-23 11:24:44

LinuxLinux目錄Linux系統(tǒng)

2015-05-19 14:03:07

Hadoop大事件盤點

2013-11-27 15:48:56

移動中間件廠商

2018-06-03 08:49:21

2024-02-27 18:42:45

人工智能

2021-08-10 23:09:55

區(qū)塊鏈數(shù)據(jù)技術(shù)

2012-01-13 16:00:05

愛國者馮軍蘋果

2022-09-01 13:25:54

isEmptyisBlank

2019-03-21 15:50:50

區(qū)塊鏈比特幣編程語言

2022-09-26 12:17:14

clamp() 函數(shù)CSS

2017-09-23 15:17:21

散熱筆記本電腦藍(lán)屏

2022-02-22 08:55:29

SelectPoll/ Epoll

2021-06-07 08:19:27

Java多線程進(jìn)程
點贊
收藏

51CTO技術(shù)棧公眾號