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

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)同步類(lèi)中的靜態(tài)方法和非靜態(tài)方法。

第一種:非靜態(tài)方法的同步
從java相關(guān)語(yǔ)法可以知道使用synchronized關(guān)鍵字來(lái)定義方法就會(huì)鎖定類(lèi)中所用使用synchroniezd關(guān)鍵字定義的靜態(tài)方法和非靜態(tài)方法,但是這有點(diǎn)不好理解,如果要synchronized塊,來(lái)達(dá)到這樣的效果,就不難理解為什么會(huì)產(chǎn)生這種效果了,如果使用synchronized來(lái)鎖定類(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)類(lèi)中使用synchronized塊中,this只表示內(nèi)類(lèi),和外類(lèi)(OuterClass)沒(méi)有關(guān)系。但是內(nèi)類(lèi)中的非靜態(tài)方法和外類(lèi)的非靜態(tài)方法也可以同步。如果在內(nèi)類(lè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í)可以使用類(lèi)的靜態(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è)類(lèi)的所有實(shí)例通過(guò)getClass方法得到的都是同一個(gè)Class對(duì)象)。我們也可以通過(guò)class使不同類(lèi)的靜態(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)文章

  • Java中的WeakHashMap源碼分析

    Java中的WeakHashMap源碼分析

    這篇文章主要介紹了Java中的WeakHashMap源碼分析,WeakHashMap可能平時(shí)使用的頻率并不高,但是你可能聽(tīng)過(guò)WeakHashMap會(huì)進(jìn)行自動(dòng)回收吧,下面就對(duì)其原理進(jìn)行分析,需要的朋友可以參考下
    2023-09-09
  • 多線程(多窗口賣(mài)票實(shí)例講解)

    多線程(多窗口賣(mài)票實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇多線程(多窗口賣(mài)票實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 每天學(xué)Java!一分鐘了解JRE與JDK

    每天學(xué)Java!一分鐘了解JRE與JDK

    每天學(xué)Java!一分鐘了解JRE與JDK,什么是JRE?什么是JDK?什么是JVM?相信通過(guò)本文大家都會(huì)有所了解,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Java中的自旋鎖解析

    Java中的自旋鎖解析

    這篇文章主要介紹了Java中的自旋鎖解析,自旋鎖是指當(dāng)一個(gè)線程嘗試獲取某個(gè)鎖時(shí),如果該鎖已被其他線程占用,就一直循環(huán)檢測(cè)鎖是否被釋放,而不是進(jìn)入線程掛起或睡眠狀態(tài),需要的朋友可以參考下
    2023-10-10
  • Java字符串原理分析之String是否可變

    Java字符串原理分析之String是否可變

    當(dāng)我們?cè)谇舐殨r(shí),面試官很喜歡問(wèn)我們關(guān)于String的一些原理性知識(shí),比如String的不可變性、字符串的內(nèi)存分配等,為了讓大家更好地應(yīng)對(duì)面試,并理解String的底層設(shè)計(jì),接下來(lái)會(huì)給大家聊聊String的一些原理,比如String為什么具有不可變性,需要的朋友可以參考下
    2023-05-05
  • JavaSE的邏輯控制你了解嗎

    JavaSE的邏輯控制你了解嗎

    這篇文章主要為大家詳細(xì)介紹了JavaSE的邏輯控制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • 10張圖總結(jié)出并發(fā)編程最佳學(xué)習(xí)路線

    10張圖總結(jié)出并發(fā)編程最佳學(xué)習(xí)路線

    這篇文章主要介紹了并發(fā)編程的最佳學(xué)習(xí)路線,文中通過(guò)圖片介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • SpringBoot整合Swagger和Actuator的使用教程詳解

    SpringBoot整合Swagger和Actuator的使用教程詳解

    Swagger 是一套基于 OpenAPI 規(guī)范構(gòu)建的開(kāi)源工具,可以幫助我們?cè)O(shè)計(jì)、構(gòu)建、記錄以及使用 Rest API。本篇文章主要介紹的是SpringBoot整合Swagger(API文檔生成框架)和SpringBoot整合Actuator(項(xiàng)目監(jiān)控)使用教程。感興趣的朋友一起看看吧
    2019-06-06
  • Spring Boot 如何整合連接池

    Spring Boot 如何整合連接池

    這篇文章主要介紹了Spring Boot 如何整合連接池,幫助大家更好的理解和學(xué)習(xí)spring boot框架,感興趣的朋友可以了解下
    2020-11-11
  • 一起聊聊Java中的自定義異常

    一起聊聊Java中的自定義異常

    在學(xué)習(xí)Java的過(guò)程中,想必大家都一定學(xué)習(xí)過(guò)異常這個(gè)篇章,異常的基本特性和使用這里就不再多講了。本文就來(lái)和大家講講如何自定義異常
    2022-08-08

最新評(píng)論