第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

JAVA 多線程鎖介紹

1. 前言

本節(jié)內(nèi)容主要是對(duì) Java 多線程鎖進(jìn)行介紹,是對(duì)鎖的一個(gè)全方位的概述,為我們對(duì)后續(xù)深入學(xué)習(xí)不同的鎖的使用方法奠定一個(gè)良好的基礎(chǔ)。本節(jié)內(nèi)容的知識(shí)點(diǎn)如下:

  • 樂(lè)觀鎖與悲觀鎖的概念,以及兩種鎖之間的區(qū)別,這是并發(fā)編程中經(jīng)常涉及到的知識(shí)點(diǎn),這是本節(jié)課程的核心知識(shí)點(diǎn),是熱度很高的必須要掌握的知識(shí),后續(xù)還會(huì)有專門的小節(jié)進(jìn)行詳細(xì)講解;
  • 公平鎖與非公平鎖的介紹,并發(fā)編程中經(jīng)常涉及到的知識(shí)點(diǎn),需要掌握其概念與區(qū)別;
  • 獨(dú)占鎖與共享鎖的介紹,并發(fā)編程中經(jīng)常涉及到的知識(shí)點(diǎn),需要掌握其概念與區(qū)別;
  • 自旋鎖的介紹,對(duì)于自旋鎖,了解其概念即可。

2. 悲觀鎖

定義:悲觀鎖指對(duì)數(shù)據(jù)被外界修改持保守態(tài)度,認(rèn)為數(shù)據(jù)很容易就會(huì)被其他線程修改(很悲觀),所以在數(shù)據(jù)被處理前先對(duì)數(shù)據(jù)進(jìn)行加鎖,并在整個(gè)數(shù)據(jù)處理過(guò)程中,使數(shù)據(jù)處于鎖定狀態(tài)。

悲觀鎖的實(shí)現(xiàn):開(kāi)發(fā)中常見(jiàn)的悲觀鎖實(shí)現(xiàn)往往依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制,即在數(shù)據(jù)庫(kù)中,在對(duì)數(shù)據(jù)記錄操作前給記錄加排它鎖。如果獲取鎖失敗,則說(shuō)明數(shù)據(jù)正在被其他線程修改,當(dāng)前線程則等待或者拋出異常。如果獲取鎖成功,則對(duì)記錄進(jìn)行操作,然后提交事務(wù)后釋放排它鎖。

實(shí)例:Java 中的 synchronized 關(guān)鍵字就是一種悲觀鎖,一個(gè)線程在操作時(shí),其他的線程必須等待,直到鎖被釋放才可進(jìn)入方法進(jìn)行執(zhí)行,保證了線程和數(shù)據(jù)的安全性,同一時(shí)間,只能有一條線程進(jìn)入執(zhí)行。

我們用一段熟悉的代碼進(jìn)行悲觀鎖的展示。

public class Student {
    private String name;

    public synchronized String getName() {
        return name;
    }

    public synchronized void setName(String name) {
        this.name = name;
    }
}

代碼分析 :假設(shè)有 3 條線程,如下圖,線程 3 正在操作 Student 類,此時(shí)線程 1 和線程 2 必須要等待線程 3 執(zhí)行完畢方可進(jìn)入,這就是悲觀鎖。

圖片描述

3. 樂(lè)觀鎖

定義:樂(lè)觀鎖是相對(duì)悲觀鎖來(lái)說(shuō)的,它認(rèn)為數(shù)據(jù)在一般情況下不會(huì)造成沖突,所以在訪問(wèn)記錄前不會(huì)加排它鎖,而是在進(jìn)行數(shù)據(jù)提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)沖突與否進(jìn)行檢測(cè)。

樂(lè)觀鎖的實(shí)現(xiàn):依舊拿數(shù)據(jù)庫(kù)的鎖進(jìn)行比較介紹,樂(lè)觀鎖并不會(huì)使用數(shù)據(jù)庫(kù)提供的鎖機(jī)制, 一般在表中添加 version 宇段或者使用業(yè)務(wù)狀態(tài)來(lái)實(shí)現(xiàn)。 樂(lè)觀鎖直到提交時(shí)才鎖定,所以不會(huì)產(chǎn)生任何死鎖。

Java 中的樂(lè)觀鎖:我們之前所學(xué)習(xí)的 CAS 原理即是樂(lè)觀鎖技術(shù),當(dāng)多個(gè)線程嘗試使用 CAS 同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能更新變量的值,而其它線程都失敗,失敗的線程并不會(huì)被掛起,而是被告知這次競(jìng)爭(zhēng)中失敗,并可以再次嘗試。

圖片描述

Tips:我們這里所說(shuō)的對(duì)于樂(lè)觀鎖,當(dāng)多個(gè)線程嘗試使用 CAS 同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能更新變量的值,而其它線程都失敗。注意失敗兩字,失敗意味著有操作,而悲觀鎖是等待,意味著不能同時(shí)操作。

4. 悲觀鎖機(jī)制存在的問(wèn)題

  • 在多線程競(jìng)爭(zhēng)下,加鎖、釋放鎖會(huì)導(dǎo)致比較多的上下文切換和調(diào)度延時(shí),引起性能問(wèn)題;
  • 一個(gè)線程持有鎖會(huì)導(dǎo)致其它所有需要此鎖的線程掛起;
  • 如果一個(gè)優(yōu)先級(jí)高的線程等待一個(gè)優(yōu)先級(jí)低的線程釋放鎖會(huì)導(dǎo)致優(yōu)先級(jí)倒置,引起性能風(fēng)險(xiǎn)。

對(duì)比于悲觀鎖的這些問(wèn)題,另一個(gè)更加有效的鎖就是樂(lè)觀鎖。其實(shí)樂(lè)觀鎖就是:每次不加鎖而是假設(shè)沒(méi)有并發(fā)沖突而去完成某項(xiàng)操作,如果因?yàn)椴l(fā)沖突失敗就重試,直到成功為止。

5. 公平鎖與非公平鎖

分類:根據(jù)線程獲取鎖的搶占機(jī)制,鎖可以分為公平鎖和非公平鎖。

公平鎖:表示線程獲取鎖的順序是按照線程請(qǐng)求鎖的時(shí)間早晚來(lái)決定的,也就是最早請(qǐng)求鎖的線程將最早獲取到鎖。

非公平鎖:非公平鎖則在運(yùn)行時(shí)闖入,不遵循先到先執(zhí)行的規(guī)則。

ReentrantLock:ReentrantLock 提供了公平和非公平鎖的實(shí)現(xiàn)。我們本節(jié)只做介紹,后續(xù)章節(jié)會(huì)對(duì) ReentrantLock 進(jìn)行深入的講解。

6. 獨(dú)占鎖與共享鎖

分類:根據(jù)鎖只能被單個(gè)線程持有還是能被多個(gè)線程共同持有,鎖可以分為獨(dú)占鎖和共享鎖。

獨(dú)占鎖:保證任何時(shí)候都只有一個(gè)線程能得到鎖,ReentrantLock 就是以獨(dú)占鎖方式實(shí)現(xiàn)的。

共享鎖:則可以同時(shí)由多個(gè)線程持有,例如 ReadWriteLock 讀寫(xiě)鎖,它允許一個(gè)資源可以被多線程同時(shí)進(jìn)行讀操作。

獨(dú)占鎖是一種悲觀鎖,由于每次訪問(wèn)資源都先加上互斥鎖,這限制了并發(fā)性,因?yàn)樽x操作并不會(huì)影響數(shù)據(jù)的一致性,而獨(dú)占鎖只允許在同一時(shí)間由一個(gè)線程讀取數(shù)據(jù),其他線程必須等待當(dāng)前線程釋放鎖才能進(jìn)行讀取。

共享鎖則是一種樂(lè)觀鎖,它放寬了加鎖的條件,允許多個(gè)線程同時(shí)進(jìn)行讀操作。

7. 自旋鎖

由于 Java 中的線程是與操作系統(tǒng)中的線程相互對(duì)應(yīng)的,所以當(dāng)一個(gè)線程在獲取鎖(比如獨(dú)占鎖)失敗后,會(huì)被切換到內(nèi)核狀態(tài)而被掛起。

當(dāng)該線程獲取到鎖時(shí)又需要將其切換到內(nèi)核狀態(tài)而喚醒該線程。而從用戶狀態(tài)切換到內(nèi)核狀態(tài)的開(kāi)銷是比較大的,在一定程度上會(huì)影響并發(fā)性能。

自旋鎖:自旋鎖則是當(dāng)前線程在獲取鎖時(shí),如果發(fā)現(xiàn)鎖已經(jīng)被其他線程占有,它不馬上阻塞自己,在不放棄 CPU 使用權(quán)的情況下,多次嘗試獲取(默認(rèn)次數(shù)是 10,可以使用-XX:PreBlockSpinsh 參數(shù)設(shè)置該值)。

很有可能在后面幾次嘗試中其他線程己經(jīng)釋放了鎖。如果嘗試指定的次數(shù)后仍沒(méi)有獲取到鎖則當(dāng)前線程才會(huì)被阻塞掛起。由此看來(lái)自旋鎖是使用 CPU 時(shí)間換取線程阻塞與調(diào)度的開(kāi)銷,但是很有可能這些 CPU 時(shí)間白白浪費(fèi)了。

8. 小結(jié)

本節(jié)內(nèi)容為鎖的基礎(chǔ)概念介紹,其中對(duì)于悲觀鎖和樂(lè)觀鎖的講解,為本節(jié)核心知識(shí)點(diǎn),因?yàn)檫@兩種鎖在數(shù)據(jù)庫(kù)的領(lǐng)域也是應(yīng)用十分廣泛。對(duì)于本節(jié)提到的具體的鎖實(shí)現(xiàn),如 ReentrantLock ,我們?cè)诤罄m(xù)章節(jié)中會(huì)有詳細(xì)的講解。

本節(jié)內(nèi)容為基礎(chǔ)介紹,掌握本節(jié)內(nèi)容的基礎(chǔ)上,能夠更好地學(xué)習(xí)后續(xù)的章節(jié)知識(shí)。