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

淺談synchronized加鎖this和class的區(qū)別

 更新時間:2021年11月28日 14:34:30   作者:Java中文社群  
synchronized 是 Java 語言中處理并發(fā)問題的一種常用手段,本文主要介紹了synchronized加鎖this和class的區(qū)別,具有一定的參考價值,感興趣的可以了解一下

synchronized 是 Java 語言中處理并發(fā)問題的一種常用手段,它也被我們親切的稱之為“Java 內(nèi)置鎖”,由此可見其地位之高。然而 synchronized 卻有著多種用法,當(dāng)它修飾不同對象時,其意義也是不同的,下面我們一起來看。

synchronized 用法

synchronized 可以用來修飾普通方法、靜態(tài)方法和代碼塊。

① 修飾普通方法

/**
 * synchronized 修飾普通方法
 */
public synchronized void method() {
    // .......
}

當(dāng) synchronized 修飾普通方法時,被修飾的方法被稱為同步方法,其作用范圍是整個方法,作用的對象是調(diào)用這個方法的對象。

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

/**
 * synchronized 修飾靜態(tài)方法
 */
public static synchronized void staticMethod() {
    // .......
}

當(dāng) synchronized 修飾靜態(tài)的方法時,其作用的范圍是整個方法,作用對象是調(diào)用這個類的所有對象。

③ 修飾代碼塊

為了減少鎖的粒度,我們可以選擇在一個方法中的某個部分使用 synchronized 來修飾(一段代碼塊),從而實(shí)現(xiàn)對一個方法中的部分代碼進(jìn)行加鎖,實(shí)現(xiàn)代碼如下:

public void classMethod() throws InterruptedException {
    // 前置代碼...
    
    // 加鎖代碼
    synchronized (SynchronizedExample.class) {
        // ......
    }
    
    // 后置代碼...
}

以上代碼在執(zhí)行時,被修飾的代碼塊稱為同步語句塊,其作用范圍是大括號“{}”括起來的代碼塊,作用的對象是調(diào)用這個代碼塊的對象。

但以上代碼,除了可以加鎖 class 之外,還可以加鎖 this,具體示例如下:

public void classMethod() throws InterruptedException {
    // 前置處理代碼...
    synchronized (this) {
        // ......
    }
    // 后置處理代碼...
}

那問題來了,使用 synchronized 加鎖 this 和 class 的區(qū)別是什么?不都是加鎖同一個類嗎?

答案還真不是,加鎖 this 和 class 區(qū)別還是很大的。下面我們通過以下 4 個示例,來看二者之間的區(qū)別。

1.加鎖 class 共享一個類實(shí)例

首先,我們創(chuàng)建 5 個線程,調(diào)用同一個對象下 synchronized 加鎖的 class 代碼,具體示例如下:

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedExample {

    public static void main(String[] args) {
        // 創(chuàng)建當(dāng)前類實(shí)例
        final SynchronizedExample example = new SynchronizedExample();
        // 創(chuàng)建 5 個線程執(zhí)行任務(wù)
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 調(diào)用 synchronized 修飾的 class 方法
                        example.classMethod();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

    /**
     * synchronized 修飾的 class 方法
     * @throws InterruptedException
     */
    public void classMethod() throws InterruptedException {
        synchronized (SynchronizedExample.class) {
            System.out.println(String.format("當(dāng)前執(zhí)行線程:%s,執(zhí)行時間:%s",
                    Thread.currentThread().getName(), new Date()));
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

以上程序的執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,這 5 個線程共享的是同一把鎖。

2.加鎖 class 創(chuàng)建多個實(shí)例

接下來,我們創(chuàng)建 5 個線程,調(diào)用不同對象下 synchronized 加鎖的 class 代碼,具體示例如下:

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedExample {

    public static void main(String[] args) {
        // 創(chuàng)建 5 個線程執(zhí)行任務(wù)
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 創(chuàng)建類實(shí)例
                        SynchronizedExample example = new SynchronizedExample();
                        // 調(diào)用 synchronized 修飾的 class 方法
                        example.classMethod();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    /**
     * synchronized 修飾的 class 方法
     * @throws InterruptedException
     */
    public void classMethod() throws InterruptedException {
        synchronized (SynchronizedExample.class) {
            System.out.println(String.format("當(dāng)前執(zhí)行線程:%s,執(zhí)行時間:%s",
                    Thread.currentThread().getName(), new Date()));
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

以上程序的執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,雖然是不同的對象,但它們使用的仍然是同一把鎖。

3.加鎖 this 共享一個類實(shí)例

接下來,我們創(chuàng)建 5 個線程,調(diào)用 synchronized 加鎖 this 的示例。首先我們這 5 個線程調(diào)用同一個對象的加鎖方法,示例代碼如下:

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedExample {

    public static void main(String[] args) {
        // 創(chuàng)建當(dāng)前類實(shí)例
        final SynchronizedExample example = new SynchronizedExample();
        // 創(chuàng)建 5 個線程執(zhí)行任務(wù)
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 調(diào)用 synchronized 修飾的 this 方法
                        example.thisMethod();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    /**
     * synchronized 修飾的 this 方法
     * @throws InterruptedException
     */
    public void thisMethod() throws InterruptedException {
        synchronized (this) {
            System.out.println(String.format("當(dāng)前執(zhí)行線程:%s,執(zhí)行時間:%s",
                    Thread.currentThread().getName(), new Date()));
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

以上程序的執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,以上線程使用的都是同一把鎖。

4.加鎖 this 創(chuàng)建多個類實(shí)例

最后一個示例最為特殊,我們使用 synchronized 加鎖 this,讓這 5 個線程調(diào)用各自創(chuàng)建對象的方法,具體示例如下:

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedExample {

    public static void main(String[] args) {
        // 創(chuàng)建 5 個線程執(zhí)行任務(wù)
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 創(chuàng)建(多個)類實(shí)例
                        SynchronizedExample example = new SynchronizedExample();
                        // 調(diào)用 synchronized 修飾的 this 方法
                        example.thisMethod();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    /**
     * synchronized 修飾的 this 方法
     * @throws InterruptedException
     */
    public void thisMethod() throws InterruptedException {
        synchronized (this) {
            System.out.println(String.format("當(dāng)前執(zhí)行線程:%s,執(zhí)行時間:%s",
                    Thread.currentThread().getName(), new Date()));
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

以上程序的執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,當(dāng)使用 synchronized 加鎖 this 時,如果線程調(diào)用的不是同一個對象,那么這些線程之間使用的鎖都是自己獨(dú)立的鎖,這個結(jié)果就和 synchronized 加鎖 class 的結(jié)果完全不同了。

總結(jié)

通過以上 4 個示例我們可以得出結(jié)論,當(dāng)使用 synchronized 加鎖 class 時,無論共享一個對象還是創(chuàng)建多個對象,它們用的都是同一把鎖,而使用 synchronized 加鎖 this 時,只有同一個對象會使用同一把鎖,不同對象之間的鎖是不同的。

到此這篇關(guān)于淺談synchronized加鎖this和class的區(qū)別的文章就介紹到這了,更多相關(guān)synchronized this class內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java?Collection集合接口的介紹和使用詳解

    java?Collection集合接口的介紹和使用詳解

    這篇文章主要為大家介紹了java?Collection集合接口的介紹和使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 使用SpringBoot編寫一個優(yōu)雅的單元測試

    使用SpringBoot編寫一個優(yōu)雅的單元測試

    這篇文章主要為大家詳細(xì)介紹了如何使用SpringBoot編寫一個優(yōu)雅的單元測試,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-07-07
  • spring boot使用i18n時properties文件中文亂碼問題的解決方法

    spring boot使用i18n時properties文件中文亂碼問題的解決方法

    這篇文章主要介紹了spring boot使用i18n時properties文件中文亂碼問題的解決方法,需要的朋友可以參考下
    2017-11-11
  • 輕松掌握J(rèn)ava橋接模式

    輕松掌握J(rèn)ava橋接模式

    這篇文章主要幫助大家輕松掌握J(rèn)ava橋接模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Java反射之靜態(tài)加載和動態(tài)加載的簡單實(shí)例

    Java反射之靜態(tài)加載和動態(tài)加載的簡單實(shí)例

    下面小編就為大家?guī)硪黄狫ava反射之靜態(tài)加載和動態(tài)加載的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作

    JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作

    這篇文章主要介紹了JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Spring依賴注入和控制反轉(zhuǎn)詳情

    Spring依賴注入和控制反轉(zhuǎn)詳情

    這篇文章主要介紹了Spring依賴注入和控制反轉(zhuǎn)詳情,控制反轉(zhuǎn)是面向?qū)ο缶幊讨惺褂玫男g(shù)語,通過該術(shù)語,對象或?qū)ο蠹目刂茩?quán)被賦予框架或由框架提供的容器。下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • Spring Cloud 整合Apache-SkyWalking實(shí)現(xiàn)鏈路跟蹤的方法

    Spring Cloud 整合Apache-SkyWalking實(shí)現(xiàn)鏈路跟蹤的方法

    這篇文章主要介紹了Spring Cloud 整合Apache-SkyWalking鏈路跟蹤的示例代碼,代碼簡單易懂,通過圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • 一篇文章帶你深入了解Java基礎(chǔ)(2)

    一篇文章帶你深入了解Java基礎(chǔ)(2)

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Ubuntu 16.04 安裝 java 8的方法

    Ubuntu 16.04 安裝 java 8的方法

    這篇文章主要介紹了Ubuntu 16.04 安裝 java 8的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05

最新評論

大同县| 济源市| 瑞昌市| 乡宁县| 监利县| 叙永县| 渭源县| 桐庐县| 铅山县| 茶陵县| 沙湾县| 中方县| 青州市| 鹤峰县| 颍上县| 贵溪市| 辽宁省| 右玉县| 绥阳县| 利津县| 东台市| 望奎县| 阜新市| 香格里拉县| 江陵县| 静海县| 内江市| 如东县| 华蓥市| 临安市| 雅安市| 射阳县| 花垣县| 宜兰市| 惠东县| 承德市| 寿宁县| 新宾| 三门县| 辽源市| 兴文县|