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

Java?Synchronized鎖的使用詳解

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

Synchronized的用法

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

同步示例方法

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

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

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

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

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

同步靜態(tài)方法

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

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

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);
    }
}

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

同步代碼塊

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

舉個栗子:

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

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

但是這樣會影響程序的性能。因為count1++和count2++為兩個互不影響的兩個臨界區(qū)資源,當線程拿到鎖,會占用兩個資源,使得臨界區(qū)資源進行閑置等待,因此可以優(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++;
        }
    }

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

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

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

相關文章

  • java 二分法算法的實例

    java 二分法算法的實例

    這篇文章主要介紹了java 二分法算法的實例的相關資料,希望通過本文大家能夠掌握二分法,需要的朋友可以參考下
    2017-09-09
  • Java使用Poi導出Excel表格方法實例

    Java使用Poi導出Excel表格方法實例

    這篇文章主要給大家介紹了關于Java使用Poi導出Excel表格的相關資料,Java POI是一個用于操作Microsoft Office格式的Java API庫,可以使用它來導出Excel文件,需要的朋友可以參考下
    2023-10-10
  • 輕松掌握Java建造者模式

    輕松掌握Java建造者模式

    這篇文章主要幫助大家輕松掌握Java建造者模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java設計模式之觀察者模式

    Java設計模式之觀察者模式

    本文詳細講解了Java設計模式之觀察者模式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • 如何在 Spring Boot 中配置和使用 CSRF 保護

    如何在 Spring Boot 中配置和使用 CSRF 保護

    CSRF是一種網(wǎng)絡攻擊,它利用已認證用戶的身份來執(zhí)行未經(jīng)用戶同意的操作,Spring Boot 提供了內(nèi)置的 CSRF 保護機制,可以幫助您防止這種類型的攻擊,這篇文章主要介紹了Spring?Boot?中的?CSRF?保護配置的使用方法,需要的朋友可以參考下
    2023-09-09
  • Proxy實現(xiàn)AOP切面編程案例

    Proxy實現(xiàn)AOP切面編程案例

    這篇文章主要介紹了Proxy實現(xiàn)AOP切面編程案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • SpringMVC使用第三方組件實現(xiàn)文件上傳

    SpringMVC使用第三方組件實現(xiàn)文件上傳

    這篇文章主要介紹了SpringMVC使用第三方組件實現(xiàn)文件上傳,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Springboot?前后端分離項目使用?POI?生成并導出?Excel的操作方法

    Springboot?前后端分離項目使用?POI?生成并導出?Excel的操作方法

    在做一個?SpringBoot?前后端分離項目的時候,需要將數(shù)據(jù)存到?Excel中,用戶可以下載?Excel,具體實現(xiàn)是采用?Apache?強大的?POI,本文給大家介紹Springboot?前后端分離項目使用?POI?生成并導出?Excel相關知識,感興趣的朋友一起看看吧
    2023-09-09
  • Java使用鎖解決銀行取錢問題實例分析

    Java使用鎖解決銀行取錢問題實例分析

    這篇文章主要介紹了Java使用鎖解決銀行取錢問題,結合實例形式分析了java線程同步與鎖機制相關原理及操作注意事項,需要的朋友可以參考下
    2019-08-08
  • Java設計模式中的單例模式解析

    Java設計模式中的單例模式解析

    這篇文章主要介紹了Java設計模式中的單例模式解析,單例模式確保一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例,需要的朋友可以參考下
    2023-11-11

最新評論

梧州市| 措美县| 晋城| 襄樊市| 东乌| 晋宁县| 襄樊市| 沁源县| 汾阳市| 萝北县| 潼南县| 永丰县| 乌兰浩特市| 南昌市| 精河县| 舒兰市| 千阳县| 商水县| 西平县| 花莲市| 建阳市| 望奎县| 德兴市| 蒙山县| 神农架林区| 长垣县| 石城县| 海丰县| 雷州市| 上高县| 轮台县| 江口县| 庐江县| 库伦旗| 大渡口区| 武平县| 巍山| 红原县| 海盐县| 旬邑县| 温州市|