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

Java 中 synchronized的用法詳解(四種用法)

 更新時(shí)間:2015年11月09日 11:47:56   投稿:mrr  
Java語(yǔ)言的關(guān)鍵字,當(dāng)它用來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。本文給大家介紹java中 synchronized的用法,對(duì)本文感興趣的朋友一起看看吧

Java語(yǔ)言的關(guān)鍵字,當(dāng)它用來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。

 1.方法聲明時(shí)使用,放在范圍操作符(public等)之后,返回類型聲明(void等)之前.這時(shí),線程獲得的是成員鎖,即一次只能有一個(gè)線程進(jìn)入該方法,其他線程要想在此時(shí)調(diào)用該方法,只能排隊(duì)等候,當(dāng)前線程(就是在synchronized方法內(nèi)部的線程)執(zhí)行完該方法后,別的線程才能進(jìn)入.

例如:

   public synchronized void synMethod() {
    //方法體
   }

    2.對(duì)某一代碼塊使用,synchronized后跟括號(hào),括號(hào)里是變量,這樣,一次只有一個(gè)線程進(jìn)入該代碼塊.此時(shí),線程獲得的是成員鎖.例如:

   public int synMethod(int a1){
    synchronized(a1) {
     //一次只能有一個(gè)線程進(jìn)入
    }
   }

    3.synchronized后面括號(hào)里是一對(duì)象,此時(shí),線程獲得的是對(duì)象鎖.例如:

 public class MyThread implements Runnable {
  public static void main(String args[]) {
  MyThread mt = new MyThread();
  Thread t1 = new Thread(mt, "t1");
  Thread t2 = new Thread(mt, "t2");
  Thread t3 = new Thread(mt, "t3");
  Thread t4 = new Thread(mt, "t4");
  Thread t5 = new Thread(mt, "t5");
  Thread t6 = new Thread(mt, "t6");
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  t5.start();
  t6.start();
 }
 public void run() {
  synchronized (this) {
   System.out.println(Thread.currentThread().getName());
  }
 }
} 

    對(duì)于3,如果線程進(jìn)入,則得到當(dāng)前對(duì)象鎖,那么別的線程在該類所有對(duì)象上的任何操作都不能進(jìn)行.在對(duì)象級(jí)使用鎖通常是一種比較粗糙的方法。為什么要將整個(gè)對(duì)象都上鎖,而不允許其他線程短暫地使用對(duì)象中其他同步方法來訪問共享資源?如果一個(gè)對(duì)象擁有多個(gè)資源,就不需要只為了讓一個(gè)線程使用其中一部分資源,就將所有線程都鎖在外面。由于每個(gè)對(duì)象都有鎖,可以如下所示使用虛擬對(duì)象來上鎖:

class FineGrainLock {
  MyMemberClass x, y;
  Object xlock = new Object(), ylock = new Object();
  public void foo() {
   synchronized(xlock) {
     //access x here
   }
   //do something here - but don't use shared resources
   synchronized(ylock) {
     //access y here
   }
  }
  public void bar() {
   synchronized(this) {
     //access both x and y here
   }
   //do something here - but don't use shared resources
  }
 }

 4.synchronized后面括號(hào)里是類,此時(shí),線程獲得的是對(duì)象鎖.例如:

class ArrayWithLockOrder{
 private static long num_locks = 0;
 private long lock_order;
 private int[] arr;
 public ArrayWithLockOrder(int[] a)
 {
  arr = a;
  synchronized(ArrayWithLockOrder.class) {//-----這里
   num_locks++;       // 鎖數(shù)加 1。
   lock_order = num_locks; // 為此對(duì)象實(shí)例設(shè)置唯一的 lock_order。
  }
 }
 public long lockOrder()
 {
  return lock_order;
 }
 public int[] array()
 {
  return arr;
 }
 }
 class SomeClass implements Runnable
 {
 public int sumArrays(ArrayWithLockOrder a1,
            ArrayWithLockOrder a2)
 {
  int value = 0;
  ArrayWithLockOrder first = a1;    // 保留數(shù)組引用的一個(gè)
  ArrayWithLockOrder last = a2;    // 本地副本。
  int size = a1.array().length;
  if (size == a2.array().length)
  {
   if (a1.lockOrder() > a2.lockOrder()) // 確定并設(shè)置對(duì)象的鎖定
   {                   // 順序。
    first = a2;
    last = a1;
   }
   synchronized(first) {       // 按正確的順序鎖定對(duì)象。
    synchronized(last) {
     int[] arr1 = a1.array();
     int[] arr2 = a2.array();
     for (int i=0; i<size; i++)
      value += arr1[i] + arr2[i];
    }
   }
  }
  return value;
 }
 public void run() {
  //
 }
 }

對(duì)于4,如果線程進(jìn)入,則線程在該類中所有操作不能進(jìn)行,包括靜態(tài)變量和靜態(tài)方法,實(shí)際上,對(duì)于含有靜態(tài)方法和靜態(tài)變量的代碼塊的同步,我們通常用4來加鎖.

PS:synchronized 用法總結(jié)

synchronized用到不同地方對(duì)代碼產(chǎn)生的影響:

1. synchronized關(guān)鍵字修飾方法

假設(shè)P1、P2是同一個(gè)類的不同對(duì)象,這個(gè)類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都能夠調(diào)用他們。

public synchronized void method(){
  // 
}

這也就是同步方法,那這時(shí)synchronized鎖定的是調(diào)用這個(gè)同步方法對(duì)象。也就是說,當(dāng)一個(gè)對(duì)象P1在不同的線程中執(zhí)行這個(gè)同步方法時(shí),他們之間會(huì)形成互斥,達(dá)到同步的效果。同時(shí)如果該對(duì)象中有多個(gè)同步方法,則當(dāng)一個(gè)線程獲執(zhí)行對(duì)象中的一個(gè)synchronized方法,則該對(duì)象中其它同步方法也不允許別的線程執(zhí)行。但是這個(gè)對(duì)象所屬的Class所產(chǎn)生的另一對(duì)象P2卻能夠任意調(diào)用這個(gè)被加了synchronized關(guān)鍵字的方法。

上邊的示例代碼等同于如下代碼:

public void method()  {  
  synchronized (this)   
  {  
    //..  
  }  
} 

此次就是一個(gè)P1對(duì)象的對(duì)象鎖,哪個(gè)拿到了P1對(duì)象鎖的線程,才能夠調(diào)用P1的同步方法,而對(duì)P2而言,P1這個(gè)鎖和他毫不相干,程式也可能在這種情形下擺脫同步機(jī)制的控制,造成數(shù)據(jù)混亂。

2.同步塊,示例代碼如下:

public void method() { 
synchronized (this) 
{ 
//.. 
} 
} 

這時(shí),鎖就是so這個(gè)對(duì)象,每個(gè)對(duì)象對(duì)應(yīng)一個(gè)唯一的鎖,所以哪個(gè)線程拿到這個(gè)對(duì)象鎖誰(shuí)就能夠運(yùn)行他所控制的那段代碼。當(dāng)有一個(gè)明確的對(duì)象作為鎖時(shí),就能夠這樣寫程式,但當(dāng)沒有明確的對(duì)象作為鎖,只是想讓一段代碼同步時(shí),能夠創(chuàng)建一個(gè)特別的instance變量(他得是個(gè)對(duì)象)來充當(dāng)鎖:

 private byte[] lock = new byte[0]; 
  Public void method(){  
      synchronized(lock) 
      { 
        // 
      }
  }  

注:零長(zhǎng)度的byte數(shù)組對(duì)象創(chuàng)建起來將比任何對(duì)象都經(jīng)濟(jì)――查看編譯后的字節(jié)碼:生成零長(zhǎng)度的byte[]對(duì)象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

3.將synchronized作用于static 函數(shù),示例代碼如下:

Class Foo  
{  
  public synchronized static void method1()  

  {  
    //.  
  }  
  public void method2()  
  {  
    synchronized(Foo.class)  
    //
  }  
} 

這兩個(gè)同步方法都調(diào)用這個(gè)方法的對(duì)象所屬的類的類鎖(Class,而不再是由這個(gè)Class產(chǎn)生的某個(gè)具體對(duì)象了)。
能夠推斷:假如一個(gè)類中定義了一個(gè)synchronized的static函數(shù)A,也定義了一個(gè)synchronized 的instance函數(shù)B,那么這個(gè)類的同一對(duì)象Obj在多線程中分別訪問A和B兩個(gè)方法時(shí),不會(huì)構(gòu)成同步,因?yàn)樗麄兊逆i都不相同。A方法的鎖是Obj所屬的那個(gè)Class,而B的鎖是Obj所屬的這個(gè)對(duì)象。

相關(guān)文章

  • Spring?Lifecycle?和?SmartLifecycle區(qū)別面試精講

    Spring?Lifecycle?和?SmartLifecycle區(qū)別面試精講

    這篇文章主要為大家介紹了Spring?Lifecycle和SmartLifecycle的區(qū)別面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 利用Java實(shí)現(xiàn)mTLS調(diào)用

    利用Java實(shí)現(xiàn)mTLS調(diào)用

    這篇文章主要介紹使用 Java作為客戶端 與受 mTLS 保護(hù)的服務(wù)交互。為了對(duì)我們的 Java 客戶端進(jìn)行 ssl 配置,我們需要先設(shè)置一個(gè) SSLContext。這簡(jiǎn)化了事情,因?yàn)?SSLContext 可用于各種 http 客戶端,接下來我們一起進(jìn)入下面文章了解具體內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • Eclipse中實(shí)現(xiàn)JS代碼提示功能(圖文教程)

    Eclipse中實(shí)現(xiàn)JS代碼提示功能(圖文教程)

    本文通過圖文并茂的形式給大家介紹了Eclipse中實(shí)現(xiàn)JS代碼提示功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-11-11
  • Spring Kafka中@KafkaListener注解的參數(shù)與使用小結(jié)

    Spring Kafka中@KafkaListener注解的參數(shù)與使用小結(jié)

    @KafkaListener注解為開發(fā)者提供了一種聲明式的方式來定義消息監(jiān)聽器,本文主要介紹了Spring Kafka中@KafkaListener注解的參數(shù)與使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Java實(shí)現(xiàn)將容器 Map中的內(nèi)容保存到數(shù)組

    Java實(shí)現(xiàn)將容器 Map中的內(nèi)容保存到數(shù)組

    這篇文章主要介紹了Java實(shí)現(xiàn)將容器 Map中的內(nèi)容保存到數(shù)組,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringBoot中配置文件及切換方式

    SpringBoot中配置文件及切換方式

    這篇文章主要介紹了SpringBoot中配置文件及切換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Activiti進(jìn)階之組任務(wù)實(shí)現(xiàn)示例詳解

    Activiti進(jìn)階之組任務(wù)實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了Activiti進(jìn)階之組任務(wù)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • maven中no main manifest attribute的問題解決

    maven中no main manifest attribute的問題解決

    本文主要介紹了maven中no main manifest attribute的問題解決,這個(gè)錯(cuò)誤通常意味著Spring Boot應(yīng)用在啟動(dòng)時(shí)遇到了問題,下面就來具體介紹一下,感興趣的可以了解一下
    2024-08-08
  • 一文搞懂Java中的線程安全與線程同步

    一文搞懂Java中的線程安全與線程同步

    線程安全指在被多個(gè)線程訪問時(shí),程序可以持續(xù)進(jìn)行正確的處理。線程同步是指程序中用于控制不同線程間操作發(fā)生相對(duì)順序的機(jī)制。本文將通過示例詳細(xì)為大家講講二者的使用,需要的可以參考一下
    2022-06-06
  • Java遍歷HashMap的6種常見方式

    Java遍歷HashMap的6種常見方式

    這篇文章主要給大家介紹了關(guān)于Java遍歷HashMap的6種常見方式,方法包括使用keySet()、entrySet()、forEach()、迭代器以及分別遍歷鍵和值,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2025-05-05

最新評(píng)論

鄢陵县| 隆子县| 故城县| 乐昌市| 柏乡县| 会东县| 拜城县| 巴彦县| 沂源县| 昂仁县| 黄平县| 醴陵市| 会东县| 宁陵县| 华安县| 福鼎市| 无为县| 灵寿县| 绥阳县| 扎赉特旗| 梁平县| 武宁县| 通州市| 福州市| 建阳市| 西宁市| 雅江县| 灯塔市| 白银市| 长寿区| 武乡县| 涟源市| 嘉义县| 南平市| 喜德县| 英超| 沁阳市| 石嘴山市| 什邡市| 灵寿县| 庄河市|