欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java鎖synchronized面試常問總結(jié)

 更新時(shí)間:2022年12月07日 11:48:45   作者:王有志  
這篇文章主要介紹了java鎖synchronized面試常問總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

synchronized都問啥?

如果Java面試有什么是必問的,synchronized必定占據(jù)一席之地。初出茅廬時(shí)synchronized的用法,成長后synchronized的原理,可謂是Java工程師的“一生之?dāng)?rdquo;。

按照慣例,先來看synchronized的常見問題(在線Excel同步更新中):

根據(jù)統(tǒng)計(jì)數(shù)據(jù)可以總結(jié)出synchronized的5大考點(diǎn):

  • synchronized的使用方式:
    • synchronized是什么?
    • synchronized怎么用?
    • 不同用法都有什么效果?
  • synchronized的實(shí)現(xiàn)原理:
    • synchronized的特性是如何實(shí)現(xiàn)的?
    • synchronized鎖升級的原理。

今天我們先來看synchronized的基礎(chǔ)部分。

synchronized是什么?

synchronized是Java中的關(guān)鍵字,提供了原生同步機(jī)制,實(shí)現(xiàn)互斥語義和可見性保證,通常稱為互斥鎖。

  • 互斥指的是,當(dāng)線程獲取到鎖后,其它試圖獲取鎖的線程只能阻塞;
  • 可見性指的是,synchronized修飾的語句內(nèi)修改共享變量可以立即被其它線程獲取。

互斥就意味著,同一時(shí)間只有一個(gè)線程執(zhí)行synchronized修飾的代碼,那么:

  • 無論怎么重排序,都會(huì)遵循as-if-serial語義,因此synchronized中不存在有序性問題;
  • 不主動(dòng)釋放鎖,其他線程無法執(zhí)行synchronized中代碼,無需考慮原子性問題。

因此synchronized中互斥就代表了對有序性問題和原子性問題的保證。不過前提是JSR-133中反復(fù)提到的correctly synchronized(正確的同步),舉個(gè)例子:

public class IncorrectlySynchronized {
    private Integer count = 0;
    public  void add() {
        synchronized (count) {
            count++;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        IncorrectlySynchronized incorrectlySynchronized = new IncorrectlySynchronized();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                incorrectlySynchronized.add();
            }
        });
        Thread t2 = new Thread(()-> {
            for (int i = 0; i < 10000; i++) {
                incorrectlySynchronized.add();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(incorrectlySynchronized.count);
    }
}

看似該加synchronized的地方都加了,但是結(jié)果卻會(huì)出乎意料,這就典型的錯(cuò)誤同步的例子。

synchronized鎖什么?

既然是鎖,那么synchronized鎖的是什么呢?

《The Java Language Specification》中描述(節(jié)選)到:

Each object in Java is associated with a monitor, which a thread can lock or unlock. The synchronized statement computes a reference to an object; it then attempts to perform a lock action on that object's monitor and does not proceed further until the lock action has successfully completed.

Java中每個(gè)對象都與一個(gè)監(jiān)視器關(guān)聯(lián),線程可以鎖定或者解鎖該監(jiān)視器。synchronized語句嘗試鎖定與對象關(guān)聯(lián)的監(jiān)視器,鎖定成功后才可以繼續(xù)執(zhí)行。

通常,我們將synchronized鎖定與對象關(guān)聯(lián)的監(jiān)視器理解為synchronized鎖定對象本身。

在我們知道synchronized鎖什么后,再去看用法,很多內(nèi)容就會(huì)一目了然了。

synchronized怎么用?

作為關(guān)鍵字,synchronized有兩種用法:

  • 修飾代碼塊
  • 修飾方法
    • 修飾成員方法
    • 修飾靜態(tài)方法

之前有個(gè)同事特別迷信“背技術(shù)”,為了區(qū)分不同用法的效果,背了某機(jī)構(gòu)的“線程八鎖”,但每過一段時(shí)間就會(huì)忘記。

其實(shí),知道了synchronized鎖什么,不同用法的效果自然就出來了,看一個(gè)例子:

public class SynchronizedDemo {
	public static void main(String[] args) throws InterruptedException {
	    SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
	    Thread t1 = new Thread(synchronizedDemo::lockMemberMethod1);
	    Thread t2 = new Thread(synchronizedDemo::lockMemberMethod2);
	    t1.start();
	    // 確保t1先執(zhí)行
	    TimeUnit.SECONDS.sleep(1);
	    t2.start();
	}
	private synchronized void lockMemberMethod1() {
	    System.out.println("方法1");
	    try {
	        TimeUnit.SECONDS.sleep(10);
	    } catch (InterruptedException e) {
	        e.printStackTrace();
	    }
	}
	private synchronized void lockMemberMethod2() {
	    System.out.println("方法2");
	}
}

通過實(shí)例變量調(diào)用成員方法時(shí),會(huì)隱式的傳遞this。這個(gè)例子中,t1和t2想鎖定的監(jiān)視器是誰的?synchronizedDemo對象的。t1先獲取到,那么t2只能等待t1釋放后再獲取了。

那此時(shí)的鎖定范圍是什么?synchronizedDemo對象。

修改下代碼:

public static void main(String[] args) throws InterruptedException {
	SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
	SynchronizedDemo synchronizedDemo2 = new SynchronizedDemo();
	Thread t1 = new Thread(synchronizedDemo::lockMemberMethod1);
	Thread t2 = new Thread(synchronizedDemo2::lockMemberMethod2);
	t1.start();
	t2.start();
}

t2不再爭奪synchronizedDemo而是爭奪synchronizedDemo2,結(jié)果上也能看出t1和t2之間不存在競爭關(guān)系。

那么使用synchronized修飾靜態(tài)方法和代碼塊是什么效果呢?

private static synchronized void lockStaticMethod() {
    System.out.println("靜態(tài)方法!"); 
}
private void lockCodeBlock(int count) {
    synchronized (this) {
        System.out.println("成員方法的代碼塊!");
    }
}

使用synchronized修飾靜態(tài)方法,鎖定的對象是SynchronizedDemo.class。所有SynchronizedDemo的實(shí)例對象共用同一個(gè)SynchronizedDemo.class,同一時(shí)間不同變量,只有一個(gè)線程可以執(zhí)行lockStaticMethod方法。

至于synchronized修飾代碼塊,就比較靈活了,括號(hào)中是誰就鎖定誰。如果是this就鎖定實(shí)例變量,如果是SynchronizedDemo.class效果就和修飾靜態(tài)方法一樣。

至于前面錯(cuò)誤的同步的例子,它的問題是count對象在不斷變化(Integer實(shí)現(xiàn)相關(guān))的,因此synchronized鎖定的并不是同一個(gè)對象。

結(jié)語

今天的內(nèi)容非?;A(chǔ),難度也不大。

重點(diǎn)可以放在synchronized鎖什么的部分,以及是如何推導(dǎo)出synchronized不同用法產(chǎn)生的不同效果的。這樣的方式更接近于問題的本質(zhì),也能更好的舉一反三,而不是死記硬背“線程八鎖”這種東西。

以上就是java鎖synchronized面試常問總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于java synchronized面試的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java之對象銷毀和finalize方法的使用

    Java之對象銷毀和finalize方法的使用

    這篇文章主要介紹了Java之對象銷毀和finalize方法的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • springboot使用@data注解減少不必要代碼

    springboot使用@data注解減少不必要代碼

    這篇文章主要介紹了springboot使用@data注解減少不必要代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)

    Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)

    下面小編就為大家?guī)硪黄狫ava 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java實(shí)現(xiàn)線程按序交替執(zhí)行的方法詳解

    Java實(shí)現(xiàn)線程按序交替執(zhí)行的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)線程按序交替執(zhí)行,文中的示例代碼講解詳細(xì),對我們了解線程有一定幫助,需要的可以參考一下
    2022-10-10
  • springboot+vue前后端分離項(xiàng)目中使用jwt實(shí)現(xiàn)登錄認(rèn)證

    springboot+vue前后端分離項(xiàng)目中使用jwt實(shí)現(xiàn)登錄認(rèn)證

    本文介紹了如何在SpringBoot+Vue前后端分離的項(xiàng)目中使用JWT實(shí)現(xiàn)登錄認(rèn)證,內(nèi)容包括后端的響應(yīng)工具類、JWT工具類、登錄用戶實(shí)體類、登錄接口、測試接口、過濾器、啟動(dòng)類以及前端的登錄頁面實(shí)現(xiàn),感興趣的可以了解一下
    2024-10-10
  • Spring之ShutDown?Hook死鎖現(xiàn)象解讀

    Spring之ShutDown?Hook死鎖現(xiàn)象解讀

    這篇文章主要介紹了Spring之ShutDown?Hook死鎖現(xiàn)象解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • spring cloud gateway請求跨域問題解決方案

    spring cloud gateway請求跨域問題解決方案

    這篇文章主要介紹了spring cloud gateway請求跨域問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Java使用Unsafe類的示例詳解

    Java使用Unsafe類的示例詳解

    java不能直接訪問操作系統(tǒng)底層,而是通過本地方法來訪問。Unsafe類提供了硬件級別的原子操作,這篇文章主要介紹了Java使用Unsafe類,需要的朋友可以參考下
    2021-09-09
  • java反射獲取一個(gè)object屬性值代碼解析

    java反射獲取一個(gè)object屬性值代碼解析

    這篇文章主要介紹了java反射獲取一個(gè)object屬性值代碼解析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 如何通過java獲取文件名和擴(kuò)展名

    如何通過java獲取文件名和擴(kuò)展名

    這篇文章主要介紹了如何通過java獲取文件名和擴(kuò)展名,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01

最新評論