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

Java中synchronized關(guān)鍵字修飾方法同步的用法詳解

 更新時(shí)間:2016年06月15日 12:18:24   作者:Iam42  
synchronized可以用來(lái)同步靜態(tài)和非靜態(tài)方法,下面就具體來(lái)看一下Java中synchronized關(guān)鍵字修飾方法同步的用法詳解:

Java的最基本的同步方式,即使用synchronized關(guān)鍵字來(lái)控制一個(gè)方法的并發(fā)訪問(wèn)。 每一個(gè)用synchronized關(guān)鍵字聲明的方法都是臨界區(qū)。在Java中,同一個(gè)對(duì)象的臨界區(qū),在同一時(shí)間只有一個(gè)允許被訪問(wèn)。

靜態(tài)方法則有不同的行為。用synchronized關(guān)鍵字聲明的靜態(tài)方法,同時(shí)只能夠被一個(gè)執(zhí)行線程訪問(wèn),但是其他線程可以訪問(wèn)這個(gè)對(duì)象的非靜態(tài)的synchronized方法。必須非常謹(jǐn)慎這一點(diǎn),因?yàn)閮蓚€(gè)線程可以同時(shí)訪問(wèn)一個(gè)對(duì)象的兩個(gè)不同的synchronized方法,即其中一個(gè)是靜態(tài)synchronized方法,另一個(gè)是非靜態(tài)synchronized方法。如果兩個(gè)方法都改變了相同的數(shù)據(jù),將會(huì)出現(xiàn)數(shù)據(jù)不一致的錯(cuò)誤。

synchronized塊的語(yǔ)法如下:

public void method() 
{ 
  synchronized(表達(dá)式) 
   { 
   } 
 
} 

synchronized關(guān)鍵字有兩種用法,一種是只用于方法的定義中,另外一種是synchronized塊,我們不僅可以使用synchronized來(lái)同步一個(gè)對(duì)象變量,你也可以通synchronizedl來(lái)同步類中的靜態(tài)方法和非靜態(tài)方法。

第一種:非靜態(tài)方法的同步
從java相關(guān)語(yǔ)法可以知道使用synchronized關(guān)鍵字來(lái)定義方法就會(huì)鎖定類中所用使用synchroniezd關(guān)鍵字定義的靜態(tài)方法和非靜態(tài)方法,但是這有點(diǎn)不好理解,如果要synchronized塊,來(lái)達(dá)到這樣的效果,就不難理解為什么會(huì)產(chǎn)生這種效果了,如果使用synchronized來(lái)鎖定類中所有的同步非靜態(tài)方法,只需要使用this作為synchronized塊的參數(shù)傳入synchronized塊中,代碼如下:

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 

 

在上面的代碼中的method1使用了synchronized塊,method2方法是用了synchronized關(guān)鍵字來(lái)定義方法,如果使用同一個(gè)Test實(shí)例時(shí),這兩個(gè)方法只要有一個(gè)在執(zhí)行,其他的方法都會(huì)因未獲得同步鎖而被堵塞。除了使用this作為synchronized塊的參數(shù),也可以使用Test.this作為synchronized塊的參數(shù)來(lái)達(dá)到同樣的效果。


在內(nèi)類中使用synchronized塊中,this只表示內(nèi)類,和外類(OuterClass)沒(méi)有關(guān)系。但是內(nèi)類中的非靜態(tài)方法和外類的非靜態(tài)方法也可以同步。如果在內(nèi)類中加個(gè)方法method3也可以使和Test里面的2個(gè)方法同步,代碼如下:

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 

上面InnerClass的method3方法與Test的method1和method2方法在同一時(shí)間內(nèi)只能有一個(gè)方法執(zhí)行。
 synchronized塊不管是正確執(zhí)行完,還是因?yàn)槌绦虺鲥e(cuò)因異常退出synchronized塊,當(dāng)前的synchronized塊所持有的同步鎖都會(huì)自動(dòng)釋放,因此在使用synchronized塊不必?fù)?dān)心同步鎖的問(wèn)題。

二、靜態(tài)方法的同步
由于在調(diào)用靜態(tài)方法時(shí),對(duì)象實(shí)例不一定被創(chuàng)建,因此,就不能使用this來(lái)同步靜態(tài)方法,而必須使用Class對(duì)象來(lái)同步靜態(tài)方法。代碼如下:

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 

在同步靜態(tài)方法時(shí)可以使用類的靜態(tài)字段class來(lái)得到class對(duì)象,在上例中method1和method2方法只有一個(gè)方法執(zhí)行,除了使用class字段可以得到class對(duì)象,還可以通過(guò)實(shí)例的getClass()方法獲取class對(duì)象,代碼如下:

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 

 
在上面的代碼中,我們通過(guò)一個(gè)public的靜態(tài)對(duì)象得到Test的一個(gè)實(shí)例,并通過(guò)這個(gè)實(shí)例的getClass方法獲取一個(gè)class對(duì)象(注意一個(gè)類的所有實(shí)例通過(guò)getClass方法得到的都是同一個(gè)Class對(duì)象)。我們也可以通過(guò)class使不同類的靜態(tài)方法同步,代碼如下:

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 

 
注意:在使用synchronized塊來(lái)同步方法時(shí),非靜態(tài)方法可以通過(guò)this來(lái)同步,而靜態(tài)方法必須使用class對(duì)象來(lái)同步,但是非靜態(tài)方法也可以通過(guò)使用class來(lái)同步靜態(tài)方法。但是靜態(tài)方法中不能使用this來(lái)同步非靜態(tài)方法。這點(diǎn)在使用synchronized塊需要注意。

Note
synchronized關(guān)鍵字會(huì)降低應(yīng)用程序的性能,因此只能在并發(fā)情景中需要修改共享數(shù)據(jù)的方法上使用它。如果多個(gè)線程訪問(wèn)同一個(gè)synchronized方法,則只有一個(gè)線程可以訪問(wèn),其他線程將等待。如果方法聲明沒(méi)有使用synchronized關(guān)鍵字,所有的線程都能在同一時(shí)間執(zhí)行這個(gè)方法,因而總運(yùn)行時(shí)間降低。如果已知一個(gè)方法不會(huì)被一個(gè)以上線程調(diào)用,則無(wú)需使用synchronized關(guān)鍵字聲明之。

可以遞歸調(diào)用被synchronized聲明的方法。當(dāng)線程訪問(wèn)一個(gè)對(duì)象的同步方法時(shí),它還可以調(diào)用這個(gè)對(duì)象的其他的同步方法,也包含正在執(zhí)行的方法,而不必再次去獲取這個(gè)方法的訪問(wèn)權(quán)。

我們可以通過(guò)synchronized關(guān)鍵字來(lái)保護(hù)代碼塊(而不是整個(gè)方法)的訪問(wèn)。應(yīng)該這樣利用synchronized關(guān)鍵字:方法的其余部分保持在synchronized代碼塊之外,以獲取更好的性能。臨界區(qū)(即同一時(shí)間只能被一個(gè)線程訪問(wèn)的代碼塊)的訪問(wèn)應(yīng)該盡可能的短。例如在獲取一幢樓人數(shù)的操作中,我們只使用synchronized關(guān)鍵字來(lái)保護(hù)對(duì)人數(shù)更新的指令,并讓其他操作不使用共享數(shù)據(jù)。當(dāng)這樣使用synchronized關(guān)鍵字時(shí),必須把對(duì)象引用作為傳入?yún)?shù)。同一時(shí)間只有一個(gè)線程被允許訪問(wèn)這個(gè)synchronized代碼。通常來(lái)說(shuō),我們使用this關(guān)鍵字來(lái)引用正在執(zhí)行的方法所屬的對(duì)象:

synchronized(this){
  //Java code
}

相關(guān)文章

  • springboot加載json配置全過(guò)程

    springboot加載json配置全過(guò)程

    Spring Boot加載JSON配置的步驟:實(shí)現(xiàn)PropertySourceLoader接口,創(chuàng)建spring.factories文件,并在resources下添加application.json,通過(guò)指定spring.profiles.active屬性來(lái)激活配置文件
    2025-12-12
  • 關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Required

    關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Requ

    這篇文章主要介紹了關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Required,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 利用Spring Cloud Config結(jié)合Bus實(shí)現(xiàn)分布式配置中心的步驟

    利用Spring Cloud Config結(jié)合Bus實(shí)現(xiàn)分布式配置中心的步驟

    這篇文章主要介紹了利用Spring Cloud Config結(jié)合Bus實(shí)現(xiàn)分布式配置中心的相關(guān)資料,文中通過(guò)示例代碼將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友下面來(lái)一起看看吧
    2018-05-05
  • SpringBoot項(xiàng)目集成日志的實(shí)現(xiàn)方法

    SpringBoot項(xiàng)目集成日志的實(shí)現(xiàn)方法

    這篇文章主要介紹了SpringBoot項(xiàng)目集成日志的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • SpringBoot整合mybatis-generator插件流程詳細(xì)講解

    SpringBoot整合mybatis-generator插件流程詳細(xì)講解

    這篇文章主要介紹了SpringBoot整合mybatis-generator插件流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • Java Lambda表達(dá)式入門示例

    Java Lambda表達(dá)式入門示例

    這篇文章主要介紹了Java Lambda表達(dá)式,結(jié)合簡(jiǎn)單實(shí)例形式分析了Lambda表達(dá)式功能、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • spring validation多層對(duì)象校驗(yàn)教程

    spring validation多層對(duì)象校驗(yàn)教程

    這篇文章主要介紹了spring validation多層對(duì)象校驗(yàn)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java教程之java程序編譯運(yùn)行圖解(java程序運(yùn)行)

    java教程之java程序編譯運(yùn)行圖解(java程序運(yùn)行)

    最近重新復(fù)習(xí)了一下java基礎(chǔ),在使用javap的過(guò)程中遇到了一些問(wèn)題,這里便講講對(duì)于一個(gè)類文件如何編譯、運(yùn)行、反編譯的。也讓自己加深一下印象
    2014-03-03
  • Java捕獲ThreadPoolExecutor內(nèi)部線程異常的四種方法

    Java捕獲ThreadPoolExecutor內(nèi)部線程異常的四種方法

    這篇文章主要為大家詳細(xì)介紹了Java捕獲ThreadPoolExecutor內(nèi)部線程異常的四種方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-03-03
  • Java線程池隊(duì)列LinkedBlockingDeque

    Java線程池隊(duì)列LinkedBlockingDeque

    這篇文章主要為大家介紹了Java線程池隊(duì)列LinkedBlockingDeque示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論

建始县| 靖西县| 凤山县| 武山县| 蚌埠市| 叙永县| 通海县| 石泉县| 新津县| 兰州市| 博罗县| 湘乡市| 奉化市| 磐安县| 望都县| 霸州市| 开远市| 武鸣县| 林口县| 吴忠市| 江津市| 乌兰察布市| 江北区| 冀州市| 内乡县| 循化| 松江区| 牟定县| 淄博市| 泊头市| 湘阴县| 历史| 福鼎市| 建平县| 田林县| 云南省| 昌江| 中牟县| 资兴市| 错那县| 清涧县|