最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)編程必備之Synchronized關(guān)鍵字深入解析

 更新時(shí)間:2025年04月02日 16:46:06   作者:權(quán)^  
本文我們深入探索了Java中的Synchronized關(guān)鍵字,包括其互斥性和可重入性的特性,文章詳細(xì)介紹了Synchronized的三種使用方式:修飾代碼塊、修飾普通方法和修飾靜態(tài)方法,感興趣的朋友一起看看吧

一、前言

在Java多線程編程中,線程安全是非常重要的一個(gè)概念。為了防止多個(gè)線程同時(shí)訪問(wèn)共享資源時(shí)出現(xiàn)數(shù)據(jù)不一致或其他競(jìng)態(tài)條件問(wèn)題,Java提供了synchronized關(guān)鍵字和監(jiān)視器鎖(Monitor Lock)機(jī)制。這個(gè)博客將深入探討synchronized的原理、使用場(chǎng)景以及與監(jiān)視器鎖的關(guān)系。

二、Synchronized關(guān)鍵字

synchronized是Java中的一個(gè)關(guān)鍵字,用于在多線程環(huán)境中控制對(duì)共享資源的訪問(wèn)。當(dāng)一個(gè)線程執(zhí)行synchronized修飾的方法或代碼塊時(shí),其他線程將無(wú)法訪問(wèn)相同的資源,直到當(dāng)前線程釋放資源鎖。

2.1 Synchronized的特性

1. 互斥

Synchronized 會(huì)起到互斥效果, 某個(gè)線程執(zhí)行到某個(gè)對(duì)象的 synchronized 中時(shí), 其他線程如果也執(zhí)行到同一個(gè)對(duì)象 synchronized 就會(huì)阻塞等待。

• 進(jìn)入 synchronized 修飾的代碼塊, 相當(dāng)于 加鎖
• 退出 synchronized 修飾的代碼塊, 相當(dāng)于 解鎖

   synchronized (locker){
                for (int i = 0; i < 5000; i++) {
                    count++;
                }
            }

synchronized用的鎖是存在Java對(duì)象頭里的。

可以粗略理解成, 每個(gè)對(duì)象在內(nèi)存中存儲(chǔ)的時(shí)候, 都存有一塊內(nèi)存表示當(dāng)前的 “鎖定” 狀態(tài)(類(lèi)似于廁所
的 “有人/無(wú)人”)。
如果當(dāng)前是 “無(wú)人” 狀態(tài), 那么就可以使用, 使用時(shí)需要設(shè)為 “有人” 狀態(tài)。
如果當(dāng)前是 “有人” 狀態(tài), 那么其他人無(wú)法使用, 只能排隊(duì)。

理解 “阻塞等待”。
針對(duì)每?把鎖, 操作系統(tǒng)內(nèi)部都維護(hù)了?個(gè)等待隊(duì)列. 當(dāng)這個(gè)鎖被某個(gè)線程占有的時(shí)候, 其他線程嘗試
進(jìn)行加鎖, 就加不上了, 就會(huì)阻塞等待, ?直等到之前的線程解鎖之后, 由操作系統(tǒng)喚醒?個(gè)新的線程,
再來(lái)獲取到這個(gè)鎖.

注意:

• 上一個(gè)線程解鎖之后, 下一個(gè)線程并不是立即就能獲取到鎖。而是要靠操作系統(tǒng)來(lái) “喚醒”. 這也就
是操作系統(tǒng)線程調(diào)度的一部分工作。
• 假設(shè)有 A B C 三個(gè)線程, 線程 A 先獲取到鎖, 然后 B 嘗試獲取鎖, 然后 C 再?lài)L試獲取鎖, 此時(shí) B 和 C
都在阻塞隊(duì)列中排隊(duì)等待.。但是當(dāng) A 釋放鎖之后, 雖然 B 比 C 先來(lái)的, 但是 B 不一定就能獲取到鎖,
而是和 C 重新競(jìng)爭(zhēng), 并不遵守先來(lái)后到的規(guī)則。
synchronized的底層是使用操作系統(tǒng)的mutex lock實(shí)現(xiàn)的。

2. 可重入

synchronized 同步塊對(duì)同?條線程來(lái)說(shuō)是可重入的,不會(huì)出現(xiàn)自己把自己鎖死的問(wèn)題。

理解 “把自己鎖死”

?個(gè)線程沒(méi)有釋放鎖, 然后又嘗試再次加鎖。
第?次加鎖, 加鎖成功
lock();
第?次加鎖, 鎖已經(jīng)被占用, 阻塞等待
lock();
按照之前對(duì)于鎖的設(shè)定, 第二次加鎖的時(shí)候, 就會(huì)阻塞等待. 直到第一次的鎖被釋放, 才能獲取到第二
個(gè)鎖.。但是釋放第?個(gè)鎖也是由該線程來(lái)完成, 結(jié)果這個(gè)線程已經(jīng)躺平了, 啥都不想干了, 也就無(wú)法進(jìn)行解鎖操作. 這時(shí)候就會(huì)死鎖。

Java 中的 synchronized可重?鎖, 因此沒(méi)有上面的問(wèn)題。

for (int i = 0; i < 50000; i++) {
 synchronized (locker) {
 synchronized (locker) {
             count++;
           }
      }
}

在可重入鎖的內(nèi)部, 包含了 “線程持有者” 和 “計(jì)數(shù)器” 兩個(gè)信息。
• 如果某個(gè)線程加鎖的時(shí)候, 發(fā)現(xiàn)鎖已經(jīng)被人占用, 但是恰好占用的正是自己, 那么仍然可以繼續(xù)獲取到鎖, 并讓計(jì)數(shù)器自增。
• 解鎖的時(shí)候計(jì)數(shù)器遞減為 0 的時(shí)候, 才真正釋放鎖. (才能被別的線程獲取到)

三、synchronized 的使用示例

synchronized 本質(zhì)上要修改指定對(duì)象的 “對(duì)象頭”。從使用角度來(lái)看,synchronized 也勢(shì)必要搭配?個(gè)具體的對(duì)象來(lái)使用。

3.1 修飾代碼塊: 明確指定鎖哪個(gè)對(duì)象

1.鎖任意對(duì)象

public class Synchrinized1 {
    private static int count;
    public static void main(String[] args) {
        Object locker=new Object();
        Thread t1=new Thread(()->{
            for (int i = 0; i <10000 ; i++) {
                synchronized (locker){
                    count++;//鎖任意對(duì)象
                }
            }
        });
    }
}

2.鎖當(dāng)前對(duì)象

public class Synchrinized1 {
    private static int count;
    public static void main(String[] args) {
        Object locker=new Object();
        Thread t1=new Thread(()->{
            for (int i = 0; i <10000 ; i++) {
                synchronized (this){
                    count++;//鎖當(dāng)前對(duì)象
                }
            }
        });
    }
}

3.2直接修飾普通方法

public class Synchronized2{
    public int count=0;
    synchronized public void methond(){
        count++;
    }
}

3.3 修飾靜態(tài)方法

public class Synchronized{
    public static int count=0;
   public static synchronized void methon(){
        count++;
    }
}

四 、監(jiān)視器鎖(Monitor Lock)

Monitor Lock(監(jiān)視器鎖)是一種高級(jí)同步機(jī)制,底層實(shí)現(xiàn)了synchronized關(guān)鍵字的功能。每個(gè)對(duì)象都關(guān)聯(lián)一個(gè)監(jiān)視器鎖,當(dāng)線程進(jìn)入synchronized塊時(shí),線程會(huì)獲取該對(duì)象的監(jiān)視器鎖。

4.1 監(jiān)視器鎖的特點(diǎn)

  • 互斥性:同一時(shí)間只有一個(gè)線程可以持有監(jiān)視器鎖。
  • 可重入性:同一線程可以多次獲取已持有的監(jiān)視器鎖。
  • 鎖升級(jí):從未鎖定狀態(tài)偏向鎖,再到輕量級(jí)鎖,最終升級(jí)為重量級(jí)鎖。

4.2 Synchronized的底層實(shí)現(xiàn)

synchronized關(guān)鍵字的實(shí)現(xiàn)依賴(lài)于JVM,而JVM底層使用了監(jiān)視器鎖(Monitor Lock)來(lái)實(shí)現(xiàn)線程的同步。

當(dāng)線程執(zhí)行synchronized代碼時(shí),JVM會(huì)檢查是否已經(jīng)獲得了監(jiān)視器鎖:

  • 如果未加鎖,當(dāng)前線程會(huì)嘗試獲取鎖。
  • 如果已加鎖,當(dāng)前線程將被阻塞,直到鎖被釋放。

4.3 onitor Lock的狀態(tài)

一個(gè)監(jiān)視器鎖有以下四種狀態(tài):

  • 未鎖定狀態(tài):任何線程都可以競(jìng)爭(zhēng)鎖。
  • 偏向鎖狀態(tài):只允許一個(gè)線程持有鎖,減少競(jìng)爭(zhēng)。
  • 輕量級(jí)鎖狀態(tài):多個(gè)線程競(jìng)爭(zhēng)鎖,但未發(fā)生旋轉(zhuǎn)或阻塞。
  • 重量級(jí)鎖狀態(tài):線程競(jìng)爭(zhēng)激烈,鎖被線程阻塞等待。

4.4 Synchronized與ReentrantLock的比較

4.5 常見(jiàn)問(wèn)題及解決方案

1. 避免過(guò)度同步

過(guò)度同步會(huì)降低并發(fā)性能,應(yīng)盡量縮小同步范圍。

2. 避免死鎖

死鎖是由于多個(gè)線程互相持有對(duì)方資源而導(dǎo)致的??梢酝ㄟ^(guò)如下方式避免:

  • 按順序加鎖:對(duì)多個(gè)鎖的加鎖順序進(jìn)行統(tǒng)一。
  • 避免嵌套鎖:減少嵌套使用鎖的場(chǎng)景。

3. 數(shù)據(jù)一致性問(wèn)題

在單例模式或共享變量的場(chǎng)景中,必須確保所有修改共享資源的操作都在同步塊內(nèi)。

五、總結(jié)

通過(guò)本文,我們深入探索了Java中的Synchronized關(guān)鍵字,包括其互斥性和可重入性的特性。文章詳細(xì)介紹了Synchronized的三種使用方式:修飾代碼塊、修飾普通方法和修飾靜態(tài)方法。同時(shí),我們還解析了監(jiān)視器鎖(Monitor Lock)的底層實(shí)現(xiàn),以及SynchronizedReentrantLock的對(duì)比。最后,文章總結(jié)了并發(fā)編程中常見(jiàn)問(wèn)題的解決方案,如避免過(guò)度同步、防止死鎖和保持?jǐn)?shù)據(jù)一致性。本文旨在幫助開(kāi)發(fā)者更好地理解和使用Synchronized,從而編寫(xiě)出高效、安全的并發(fā)程序。

到此這篇關(guān)于Java并發(fā)編程必備之Synchronized關(guān)鍵字深入解析的文章就介紹到這了,更多相關(guān)Java Synchronized關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文探索Java文件讀寫(xiě)更高效方式

    一文探索Java文件讀寫(xiě)更高效方式

    這篇文章主要介紹了一文探索Java文件讀寫(xiě)更高效方式,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值需要的小伙伴可以參考一下
    2022-07-07
  • Java調(diào)用微信支付功能的方法示例代碼

    Java調(diào)用微信支付功能的方法示例代碼

    這篇文章主要介紹了Java調(diào)用微信支付功能的方法示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明

    Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明

    這篇文章主要介紹了Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot 過(guò)濾器、攔截器、監(jiān)聽(tīng)器對(duì)比及使用場(chǎng)景分析

    SpringBoot 過(guò)濾器、攔截器、監(jiān)聽(tīng)器對(duì)比及使用場(chǎng)景分析

    過(guò)濾器是處于客戶端和服務(wù)器資源文件之間的一道過(guò)濾網(wǎng),這篇文章主要介紹了SpringBoot 過(guò)濾器、攔截器、監(jiān)聽(tīng)器對(duì)比及使用場(chǎng)景分析,需要的朋友可以參考下
    2021-05-05
  • Kafka?在?java?中的基本使用步驟

    Kafka?在?java?中的基本使用步驟

    本文給大家介紹Kafka在java中的基本使用,本文分步驟結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-09-09
  • Java中對(duì)于并發(fā)問(wèn)題的處理思路分享

    Java中對(duì)于并發(fā)問(wèn)題的處理思路分享

    并發(fā)粗暴的解釋就是一段代碼,在同一時(shí)間段內(nèi),被多個(gè)線程同時(shí)處理的情況就是并發(fā)現(xiàn)象。這篇文章和大家分享了一些對(duì)于并發(fā)問(wèn)題的處理思路,需要的可以參考一下
    2023-02-02
  • 線程池之exectue與submit的區(qū)別及說(shuō)明

    線程池之exectue與submit的區(qū)別及說(shuō)明

    這篇文章主要介紹了線程池之exectue與submit的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 一文淺析SpringBoot3中的異步批量處理操作

    一文淺析SpringBoot3中的異步批量處理操作

    對(duì)于使用 Spring Boot 3 框架的開(kāi)發(fā)者而言,掌握異步批量處理操作至關(guān)重要,本文將深入探討 Spring Boot 3 中異步批量處理操作的方方面面,幫助各位開(kāi)發(fā)者在實(shí)際項(xiàng)目中更好地應(yīng)用這一強(qiáng)大功能
    2025-12-12
  • java中接口冪等性的五種實(shí)現(xiàn)方法

    java中接口冪等性的五種實(shí)現(xiàn)方法

    在java中保證接口冪等性,即多次調(diào)用同一接口產(chǎn)生與單次調(diào)用相同的結(jié)果,不會(huì)引發(fā)副作用,需要結(jié)合業(yè)務(wù)場(chǎng)景選擇合適的方案,下面就來(lái)介紹五種實(shí)現(xiàn)方法,感興趣的可以了解一下
    2025-09-09
  • Java中字符串常見(jiàn)題之String相關(guān)講解

    Java中字符串常見(jiàn)題之String相關(guān)講解

    今天小編就為大家分享一篇關(guān)于Java中字符串常見(jiàn)題之String相關(guān)講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01

最新評(píng)論

于田县| 十堰市| 富裕县| 东安县| 婺源县| 寻乌县| 瓦房店市| 宜良县| 景泰县| 涿州市| 车致| 南靖县| 化德县| 图片| 金昌市| 绿春县| 剑河县| 类乌齐县| 长春市| 宝丰县| 登封市| 正阳县| 呼和浩特市| 林西县| 皋兰县| 巫山县| 巴彦淖尔市| 怀柔区| 昌平区| 张家川| 五华县| 镇原县| 深泽县| 镇平县| 镇安县| 都安| 龙陵县| 余庆县| 隆尧县| 博野县| 社会|