對(duì)象級(jí)別鎖 vs 類(lèi)級(jí)別鎖 – Java

簡(jiǎn)書(shū) 賈小強(qiáng)
轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝!

同步針對(duì)的是多線程。同步的方法或代碼塊同時(shí)只能由一個(gè)線程執(zhí)行。

Java支持多線程來(lái)執(zhí)行。這可能會(huì)導(dǎo)致兩個(gè)或多個(gè)線程訪問(wèn)同一個(gè)字段或?qū)ο?。同步是一個(gè)使所有并發(fā)執(zhí)行的線程同步的過(guò)程。同步避免了由于共享內(nèi)存視圖不一致而導(dǎo)致的內(nèi)存一致性錯(cuò)誤。當(dāng)一個(gè)方法被聲明為同步時(shí),如果一個(gè)線程正在執(zhí)行同步方法,線程保存該方法對(duì)象的監(jiān)視器(monitor),同時(shí)該線程被阻塞,直到該線程釋放監(jiān)視器(monitor)為止。

同步在Java中使用synchronized關(guān)鍵字實(shí)現(xiàn)。可以在類(lèi)中定義的方法或塊使用同步關(guān)鍵字。關(guān)鍵字不能與類(lèi)定義中的局部變量一起使用。

對(duì)象級(jí)別鎖

對(duì)象級(jí)別鎖是一種當(dāng)您想同步非靜態(tài)方法或非靜態(tài)代碼塊時(shí),只有一個(gè)線程能夠在類(lèi)的給定實(shí)例上執(zhí)行代碼塊的機(jī)制。應(yīng)該始終這樣做,使實(shí)例級(jí)數(shù)據(jù)線程安全。這可以做如下:

public class DemoClass
{
    public synchronized void demoMethod(){}
}

public class DemoClass
{
    public void demoMethod(){
        synchronized (this)
        {
            //other thread safe code
        }
    }
}

public class DemoClass
{
    private final Object lock = new Object();
    public void demoMethod(){
        synchronized (lock)
        {
            //other thread safe code
        }
    }
}

類(lèi)級(jí)別鎖

類(lèi)級(jí)鎖定防止在運(yùn)行時(shí)多個(gè)線程進(jìn)入所有可用實(shí)例中的同步塊中。這意味著,如果在運(yùn)行時(shí)有100 DemoClass實(shí)例,那么只有一個(gè)線程可以在同一時(shí)間在任何一個(gè)實(shí)例上執(zhí)行demomethod(),對(duì)其他線程而言所有其他的實(shí)例將被鎖。這樣做總是為了使靜態(tài)數(shù)據(jù)線程安全。

public class DemoClass
{
    public synchronized static void demoMethod(){}
}

public class DemoClass
{
    public void demoMethod(){
        synchronized (DemoClass.class)
        {
            //other thread safe code
        }
    }
}

public class DemoClass
{
    private final static Object lock = new Object();
    public void demoMethod(){
        synchronized (lock)
        {
            //other thread safe code
        }
    }
}

一些重要的事項(xiàng)

  1. 在Java中為了保證沒(méi)有兩個(gè)線程可以同時(shí)執(zhí)行一個(gè)同步的方法,這就需要相同的鎖。
  2. 同步關(guān)鍵字只能用于方法,代碼塊和final字段。這些方法或塊既可以是靜態(tài)的也可以是非靜態(tài)的。
  3. 當(dāng)有一個(gè)線程進(jìn)入Java同步方法或塊的時(shí)候獲取鎖,離開(kāi)Java同步方法或塊的時(shí)候釋放鎖。線程完成同步方法,或由于任何錯(cuò)誤或異常,鎖都會(huì)被釋放。
  4. Java同步關(guān)鍵詞是可重入的,這意味著如果一個(gè)Java同步方法調(diào)用另一個(gè)需要相同的鎖的同步方法,當(dāng)前線程持有鎖,能直接進(jìn)入,不需要有獲取鎖。
  5. 如果使用Java同步塊的對(duì)象為空J(rèn)ava同步將拋出NullPointerException。例如,在上面的代碼示例,如果鎖被初始化為null,同步(鎖)將拋出NullPointerException。
  6. Java同步會(huì)消耗您的應(yīng)用程序性能。所以絕對(duì)必要時(shí)才使用同步。另外,考慮使用同步代碼塊來(lái)同步代碼中的關(guān)鍵部分。
  7. 靜態(tài)同步和非靜態(tài)同步方法可能同時(shí)或并發(fā)地運(yùn)行,因?yàn)樗鼈冩i定在不同的對(duì)象上。
  8. 根據(jù)Java語(yǔ)言規(guī)范不能使用同步關(guān)鍵詞在構(gòu)造函數(shù)上,這是違法的,會(huì)導(dǎo)致編譯錯(cuò)誤。
  9. 不要同步非final字段。因?yàn)榉莊inal字段的引用可能隨時(shí)改變,不同的線程可能在不同的對(duì)象上同步,即根本不同步。最好是使用字符串類(lèi),它已經(jīng)是不可變的,并且聲明為final的。

Happy Learning !!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,697評(píng)論 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的開(kāi)發(fā)和運(yùn)行環(huán)境,java的開(kāi)發(fā)工...
    ZaneInTheSun閱讀 2,812評(píng)論 0 11
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,802評(píng)論 11 349
  • 如果你看到下面的圖片,請(qǐng)換成咱倆曾經(jīng)的情侶頭像 還記得吧,這是我們青春年少 我曾想過(guò),如果當(dāng)時(shí)我情商高一些,...
    蘇拉威西的海閱讀 365評(píng)論 0 0
  • "一眼愛(ài)情"多存在于少數(shù)人身上,更多的是慢慢熟悉,從朋友到伴侶的轉(zhuǎn)變??赡茉谖遗c你成為朋友的時(shí)候我們都沒(méi)有想過(guò)后來(lái)...
    情緒販賣(mài)機(jī)閱讀 282評(píng)論 0 0

友情鏈接更多精彩內(nèi)容