亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java?Synchronized鎖的使用詳解

 更新時(shí)間:2022年10月26日 11:24:08   作者:小威要向諸佬學(xué)習(xí)呀  
在多線程并發(fā)問(wèn)題中,常用Synchronized鎖解決問(wèn)題。本篇文章主要介紹了并發(fā)編程中Synchronized鎖的用法知識(shí)記錄,感興趣的小伙伴可以了解一下

Synchronized的用法

在多線程并發(fā)問(wèn)題中,常用Synchronized鎖解決問(wèn)題。Synchronized鎖通常用于同步示例方法,同步靜態(tài)方法,同步代碼塊等。

同步示例方法

我們可能自己使用過(guò)在方法前加Synchronized鎖修飾,在多線程并發(fā)同時(shí)調(diào)用同一個(gè)實(shí)例化對(duì)象時(shí),如果這個(gè)方法加上了Synchronized鎖,那么也是線程安全的。
舉個(gè)栗子:

package Thread;

import java.util.stream.IntStream;

public class ThreadTest {
    private Long count=0L;
    public void incrementCount(){
        count++;
    }
    public Long execute() throws InterruptedException {
        Thread thread1=new Thread(()->{
            IntStream.range(0,1000).forEach((i)->incrementCount());//線程1循環(huán)1000次
        });
        Thread thread2=new Thread(()->{
            IntStream.range(0,1000).forEach((i)->incrementCount());//線程2循環(huán)1000次
        });
        thread1.start();//開啟線程
        thread2.start();
        thread1.join();//等待線程1和線程2執(zhí)行完畢
        thread2.join();
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest=new ThreadTest();
        Long count = threadTest.execute();
        System.out.println(count);
    }
}

在上面的程序中,count變量為成員變量,在多線程同時(shí)使用時(shí)極大可能會(huì)發(fā)生錯(cuò)誤,在前面也講到過(guò)count++包含三個(gè)步驟:1.將變量count從主內(nèi)存中加載到CPU的寄存器中;2.在CPU的寄存器中執(zhí)行count++或++count的操作;3.將運(yùn)算的count++的結(jié)果寫入緩存或內(nèi)存中。兩個(gè)線程都會(huì)更新count的值到內(nèi)存中,當(dāng)其中一個(gè)線程再?gòu)膬?nèi)存中讀取數(shù)據(jù)時(shí),可能讀到的成員變量會(huì)與當(dāng)前的變量不一致,從而使得最終count的結(jié)果不為2000,因此會(huì)發(fā)生錯(cuò)誤。

如何能解決這種錯(cuò)誤?就是為incrementCount方法加鎖:

 public synchronized void incrementCount(){
        count++;
    }

這樣就能保證所得到的count最終值為2000了。

同步靜態(tài)方法

當(dāng)一個(gè)類的某個(gè)靜態(tài)方法加了synchronized鎖時(shí),就相當(dāng)于給這個(gè)類的class對(duì)象加鎖。所以無(wú)論創(chuàng)建多少個(gè)當(dāng)前類的對(duì)象調(diào)用這個(gè)被synchronized鎖修飾的靜態(tài)方法時(shí),都是線程安全的。

如上面的例子,修改如下:

package Thread;

import java.util.stream.IntStream;

public class ThreadTest {
    private static Long count=0L;
    public static synchronized void incrementCount(){
        count++;
    }
    public static Long execute() throws InterruptedException {
        Thread thread1=new Thread(()->{
            IntStream.range(0,1000).forEach((i)->incrementCount());
        });
        Thread thread2=new Thread(()->{
            IntStream.range(0,1000).forEach((i)->incrementCount());
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest threadTest=new ThreadTest();
        Long count = threadTest.execute();
        System.out.println(count);
    }
}

因此,當(dāng)多個(gè)線程并發(fā)執(zhí)行調(diào)用被synchronized鎖修飾的靜態(tài)方法時(shí),這個(gè)靜態(tài)方法是線程安全的。

同步代碼塊

前面提到加了synchronized鎖的方法在多線程并發(fā)條件下是線程安全的,但是在執(zhí)行業(yè)務(wù)邏輯過(guò)多的代碼塊時(shí),可能會(huì)影響程序的執(zhí)行效率。對(duì)于此時(shí),可以把一個(gè)方法分成多個(gè)小的臨界區(qū)。

舉個(gè)栗子:

    private Long count1=0L;
    private Long count2=0L;
    public synchronized void incrementCount(){
        count1++;
        count2++;
    }

在上面的代碼中,count1和count2為兩個(gè)不同的自增操作,因此對(duì)于count1和count2來(lái)說(shuō)是兩個(gè)不同的臨界區(qū)資源。當(dāng)一個(gè)線程進(jìn)入incrementCount方法中時(shí),會(huì)對(duì)整個(gè)方法進(jìn)行加鎖,在對(duì)count1進(jìn)行自增操作時(shí),也會(huì)占用count2的資源,相當(dāng)于占用全部的資源。只有等到這個(gè)線程執(zhí)行完count1++和count2++的操作時(shí),釋放鎖時(shí),其它線程才能拿到鎖資源進(jìn)入incrementCount方法。

但是這樣會(huì)影響程序的性能。因?yàn)閏ount1++和count2++為兩個(gè)互不影響的兩個(gè)臨界區(qū)資源,當(dāng)線程拿到鎖,會(huì)占用兩個(gè)資源,使得臨界區(qū)資源進(jìn)行閑置等待,因此可以優(yōu)化代碼,讓synchronized鎖修飾代碼塊。

修改后的代碼:

    private Long count1=0L;
    private Long count2=0L;
    public Object count1Lock=new Object();
    public Object count2Lock=new Object();
    public void incrementCount(){
        synchronized (count1Lock){
            count1++;
        }
        synchronized (count2Lock){
            count2++;
        }
    }

上面代碼中,對(duì)count1和count2分別建立了對(duì)象鎖count1Lock和count2Lock,而沒(méi)有對(duì)incrementCount加鎖,意為當(dāng)一個(gè)線程進(jìn)入incrementCount方法時(shí),其他線程也能進(jìn)入此方法,當(dāng)線程1拿到count1Lock對(duì)象鎖時(shí),不影響線程2拿到count2Lock對(duì)象鎖來(lái)對(duì)count2執(zhí)行自增操作。

這樣既提高了程序的執(zhí)行效率,同時(shí),由于臨界區(qū)資源都加了鎖,incrementCount方法也是線程安全的。

到此這篇關(guān)于Java Synchronized鎖的使用詳解的文章就介紹到這了,更多相關(guān)Java Synchronized鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Hibernate環(huán)境搭建與配置方法(Hello world配置文件版)

    Hibernate環(huán)境搭建與配置方法(Hello world配置文件版)

    這篇文章主要介紹了Hibernate環(huán)境搭建與配置方法,這里演示Hello world配置文件版的具體實(shí)現(xiàn)步驟與相關(guān)代碼,需要的朋友可以參考下
    2016-03-03
  • Java 中的類和對(duì)象詳情

    Java 中的類和對(duì)象詳情

    這篇文章主要介紹了Java 中的類和對(duì)象,類可以看成是創(chuàng)建Java對(duì)象的模板,下面文章圍繞著Java 類與對(duì)象詳細(xì)內(nèi)容展開,需要的朋友可以參考一下
    2021-11-11
  • Java中ArrayList類詳細(xì)介紹

    Java中ArrayList類詳細(xì)介紹

    這篇文章主要介紹了Java中ArrayList類詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Spring MVC處理響應(yīng)的案例詳解

    Spring MVC處理響應(yīng)的案例詳解

    當(dāng)服務(wù)器向客戶端響應(yīng)數(shù)據(jù)時(shí),SpringMVC框架會(huì)使用“轉(zhuǎn)換器”(Converter)將方法的返回值進(jìn)行轉(zhuǎn)換,SpringMVC框架還會(huì)自動(dòng)使用不同的轉(zhuǎn)換器,因此這篇文章就給大家詳細(xì)介紹一下Spring MVC如何處理響應(yīng)并附上案例,需要的朋友可以參考下
    2023-06-06
  • 深入理解Java8新特性之Stream API的創(chuàng)建方式和中間操作步驟

    深入理解Java8新特性之Stream API的創(chuàng)建方式和中間操作步驟

    Stream是Java8的一大亮點(diǎn),是對(duì)容器對(duì)象功能的增強(qiáng),它專注于對(duì)容器對(duì)象進(jìn)行各種非常便利、高效的 聚合操作(aggregate operation)或者大批量數(shù)據(jù)操作。Stream API借助于同樣新出現(xiàn)的Lambda表達(dá)式,極大的提高編程效率和程序可讀性,感興趣的朋友快來(lái)看看吧
    2021-11-11
  • Java中獲取類路徑classpath的簡(jiǎn)單方法(推薦)

    Java中獲取類路徑classpath的簡(jiǎn)單方法(推薦)

    下面小編就為大家?guī)?lái)一篇Java中獲取類路徑classpath的簡(jiǎn)單方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • Python學(xué)習(xí)之書寫格式及變量命名

    Python學(xué)習(xí)之書寫格式及變量命名

    這篇文章我們給大家總結(jié)了關(guān)于Python書寫格式及變量命名,小編覺(jué)得這篇文章寫的還不錯(cuò),有興趣的朋友跟著參考學(xué)習(xí)下,希望能夠給你帶來(lái)幫助
    2021-10-10
  • Zuul 如何屏蔽服務(wù)和指定路徑

    Zuul 如何屏蔽服務(wù)和指定路徑

    這篇文章主要介紹了Zuul 如何屏蔽服務(wù)和指定路徑的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java將XML文檔轉(zhuǎn)換成json格式數(shù)據(jù)的示例

    java將XML文檔轉(zhuǎn)換成json格式數(shù)據(jù)的示例

    本篇文章主要介紹了java將XML文檔轉(zhuǎn)換成json格式數(shù)據(jù)的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 使用mtrace追蹤JVM堆外內(nèi)存泄露的方法

    使用mtrace追蹤JVM堆外內(nèi)存泄露的方法

    這篇文章主要給大家介紹了如何使用mtrace追蹤JVM堆外內(nèi)存泄露,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-09-09

最新評(píng)論