亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解java中的synchronized關(guān)鍵字

 更新時(shí)間:2015年12月02日 14:55:09   作者:Gang.Wang  
這篇文章主要介紹了java中的synchronized關(guān)鍵字,可用來(lái)給對(duì)象和方法或者代碼塊加鎖,當(dāng)它鎖定一個(gè)方法或者一個(gè)代碼塊的時(shí)候,同一時(shí)刻最多只有一個(gè)線程執(zhí)行這段代碼,感興趣的小伙伴們可以參考一下

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

一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。

二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。

三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。

四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

 五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用。

舉例說(shuō)明:  
一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。

package ths;

public class Thread1 implements Runnable { 
   public void run() { 
     synchronized(this) { 
        for (int i = 0; i < 5; i++) { 
          System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); 
        } 
     } 
   } 
   public static void main(String[] args) { 
     Thread1 t1 = new Thread1(); 
     Thread ta = new Thread(t1, "A"); 
     Thread tb = new Thread(t1, "B"); 
     ta.start(); 
     tb.start(); 
   } 
}

結(jié)果:  
     A synchronized loop 0 
     A synchronized loop 1 
     A synchronized loop 2 
     A synchronized loop 3 
     A synchronized loop 4 
     B synchronized loop 0 
     B synchronized loop 1 
     B synchronized loop 2 
     B synchronized loop 3 
     B synchronized loop 4

二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。

package ths;

public class Thread2 { 
   public void m4t1() { 
     synchronized(this) { 
        int i = 5; 
        while( i-- > 0) { 
          System.out.println(Thread.currentThread().getName() + " : " + i); 
          try { 
             Thread.sleep(500); 
          } catch (InterruptedException ie) { 
          } 
        } 
     } 
   } 
   public void m4t2() { 
     int i = 5; 
     while( i-- > 0) { 
        System.out.println(Thread.currentThread().getName() + " : " + i); 
        try { 
          Thread.sleep(500); 
        } catch (InterruptedException ie) { 
        } 
     } 
   } 
   public static void main(String[] args) { 
     final Thread2 myt2 = new Thread2(); 
     Thread t1 = new Thread( new Runnable() { public void run() { myt2.m4t1(); } }, "t1" ); 
     Thread t2 = new Thread( new Runnable() { public void run() { myt2.m4t2();  } }, "t2" ); 
     t1.start(); 
     t2.start(); 
   } 
}

結(jié)果:  
     t1 : 4 
     t2 : 4 
     t1 : 3 
     t2 : 3 
     t1 : 2 
     t2 : 2 
     t1 : 1 
     t2 : 1 
     t1 : 0 
     t2 : 0

三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。

修改Thread2.m4t2()方法:     

 public void m4t2() { 
     synchronized(this) { 
        int i = 5; 
        while( i-- > 0) { 
          System.out.println(Thread.currentThread().getName() + " : " + i); 
          try { 
             Thread.sleep(500); 
          } catch (InterruptedException ie) { 
          } 
        } 
     }

   }

結(jié)果:

     t1 : 4 
     t1 : 3 
     t1 : 2 
     t1 : 1 
     t1 : 0 
     t2 : 4 
     t2 : 3 
     t2 : 2 
     t2 : 1 
     t2 : 0

四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

修改Thread2.m4t2()方法如下:    

public synchronized void m4t2() { 
     int i = 5; 
     while( i-- > 0) { 
        System.out.println(Thread.currentThread().getName() + " : " + i); 
        try { 
          Thread.sleep(500); 
        } catch (InterruptedException ie) { 
        } 
     } 
   }

結(jié)果:  
     t1 : 4 
     t1 : 3 
     t1 : 2 
     t1 : 1 
     t1 : 0 
     t2 : 4 
     t2 : 3 
     t2 : 2 
     t2 : 1 
     t2 : 0

五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用:

package ths;

public class Thread3 { 
   class Inner { 
     private void m4t1() { 
        int i = 5; 
        while(i-- > 0) { 
          System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i); 
          try { 
             Thread.sleep(500); 
          } catch(InterruptedException ie) { 
          } 
        } 
     } 
     private void m4t2() { 
        int i = 5; 
        while(i-- > 0) { 
          System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); 
          try { 
             Thread.sleep(500); 
          } catch(InterruptedException ie) { 
          } 
        } 
     } 
   } 
   private void m4t1(Inner inner) { 
     synchronized(inner) { //使用對(duì)象鎖 
     inner.m4t1(); 
   } 
   private void m4t2(Inner inner) { 
     inner.m4t2(); 
   } 
   public static void main(String[] args) { 
     final Thread3 myt3 = new Thread3(); 
     final Inner inner = myt3.new Inner(); 
     Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1"); 
   Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2"); 
   t1.start(); 
   t2.start(); 
 } 
}

結(jié)果:

盡管線程t1獲得了對(duì)Inner的對(duì)象鎖,但由于線程t2訪問(wèn)的是同一個(gè)Inner中的非同步部分。所以兩個(gè)線程互不干擾。

     t1 : Inner.m4t1()=4 
     t2 : Inner.m4t2()=4 
     t1 : Inner.m4t1()=3 
     t2 : Inner.m4t2()=3 
     t1 : Inner.m4t1()=2 
     t2 : Inner.m4t2()=2 
     t1 : Inner.m4t1()=1 
     t2 : Inner.m4t2()=1 
     t1 : Inner.m4t1()=0 
     t2 : Inner.m4t2()=0

現(xiàn)在在Inner.m4t2()前面加上synchronized:

 private synchronized void m4t2() { 
     int i = 5; 
     while(i-- > 0) { 
        System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); 
        try { 
          Thread.sleep(500); 
        } catch(InterruptedException ie) { 
        } 
     } 
   }

結(jié)果:

盡管線程t1與t2訪問(wèn)了同一個(gè)Inner對(duì)象中兩個(gè)毫不相關(guān)的部分,但因?yàn)閠1先獲得了對(duì)Inner的對(duì)象鎖,所以t2對(duì)Inner.m4t2()的訪問(wèn)也被阻塞,因?yàn)閙4t2()是Inner中的一個(gè)同步方法。

     t1 : Inner.m4t1()=4 
     t1 : Inner.m4t1()=3 
     t1 : Inner.m4t1()=2 
     t1 : Inner.m4t1()=1 
     t1 : Inner.m4t1()=0 
     t2 : Inner.m4t2()=4 
     t2 : Inner.m4t2()=3 
     t2 : Inner.m4t2()=2 
     t2 : Inner.m4t2()=1 
     t2 : Inner.m4t2()=0
synchronized 關(guān)鍵字,它包括兩種用法:synchronized 方法synchronized 塊。 
1. synchronized 方法:通過(guò)在方法聲明中加入 synchronized關(guān)鍵字來(lái)聲明 synchronized 方法。如: 
public synchronized void accessVal(int newVal); 
synchronized 方法控制對(duì)類成員變量的訪問(wèn):每個(gè)類實(shí)例對(duì)應(yīng)一把鎖,每個(gè) synchronized 方法都必須獲得調(diào)用該方法的類實(shí)例的鎖方能執(zhí)行,否則所屬線程阻塞,方法一旦執(zhí)行,就獨(dú)占該鎖,直到從該方法返回時(shí)才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進(jìn)入可執(zhí)行狀態(tài)。這種機(jī)制確保了同一時(shí)刻對(duì)于每一個(gè)類實(shí)例,其所有聲明為 synchronized 的成員函數(shù)中至多只有一個(gè)處于可執(zhí)行狀態(tài)(因?yàn)橹炼嘀挥幸粋€(gè)能夠獲得該類實(shí)例對(duì)應(yīng)的鎖),從而有效避免了類成員變量的訪問(wèn)沖突(只要所有可能訪問(wèn)類成員變量的方法均被聲明為 synchronized)。 
在 Java 中,不光是類實(shí)例,每一個(gè)類也對(duì)應(yīng)一把鎖,這樣我們也可將類的靜態(tài)成員函數(shù)聲明為 synchronized ,以控制其對(duì)類的靜態(tài)成員變量的訪問(wèn)。 
synchronized 方法的缺陷:若將一個(gè)大的方法聲明為synchronized 將會(huì)大大影響效率,典型地,若將線程類的方法 run() 聲明為synchronized ,由于在線程的整個(gè)生命期內(nèi)它一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類任何 synchronized 方法的調(diào)用都永遠(yuǎn)不會(huì)成功。當(dāng)然我們可以通過(guò)將訪問(wèn)類成員變量的代碼放到專門的方法中,將其聲明為 synchronized ,并在主方法中調(diào)用來(lái)解決這一問(wèn)題,但是 Java 為我們提供了更好的解決辦法,那就是 synchronized 塊。 
2. synchronized 塊:通過(guò) synchronized關(guān)鍵字來(lái)聲明synchronized 塊。語(yǔ)法如下: 
synchronized(syncObject) { 
//允許訪問(wèn)控制的代碼 

synchronized 塊是這樣一個(gè)代碼塊,其中的代碼必須獲得對(duì)象 syncObject (如前所述,可以是類實(shí)例或類)的鎖方能執(zhí)行,具體機(jī)制同前所述。由于可以針對(duì)任意代碼塊,且可任意指定上鎖的對(duì)象,故靈活性較高。 

以上就是關(guān)于java synchronized關(guān)鍵字的詳細(xì)實(shí)例介紹,希望能夠幫助大家更好的學(xué)習(xí)synchronized關(guān)鍵字的用法。

相關(guān)文章

  • 向Spring IOC 容器動(dòng)態(tài)注冊(cè)bean實(shí)現(xiàn)方式

    向Spring IOC 容器動(dòng)態(tài)注冊(cè)bean實(shí)現(xiàn)方式

    這篇文章主要為大家介紹了向Spring IOC 容器動(dòng)態(tài)注冊(cè)bean實(shí)現(xiàn)方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Jaxb2實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的方法詳解

    Jaxb2實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的方法詳解

    這篇文章主要介紹了Jaxb2實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的方法,簡(jiǎn)單介紹了JAXB的概念、功能及實(shí)現(xiàn)JavaBean與xml互轉(zhuǎn)的具體操作技巧,需要的朋友可以參考下
    2017-04-04
  • 解決RedisTemplate存儲(chǔ)至緩存數(shù)據(jù)出現(xiàn)亂碼的情況

    解決RedisTemplate存儲(chǔ)至緩存數(shù)據(jù)出現(xiàn)亂碼的情況

    這篇文章主要介紹了解決RedisTemplate存儲(chǔ)至緩存數(shù)據(jù)出現(xiàn)亂碼的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • Java中Stream流Map分組方式詳細(xì)匯總

    Java中Stream流Map分組方式詳細(xì)匯總

    Stream將要處理的元素集合看作一種流,在流的過(guò)程中借助Stream?API對(duì)流中的元素進(jìn)行操作,比如篩選、排序、聚合等,下面這篇文章主要給大家介紹了關(guān)于Java中Stream流Map分組方式的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • SpringBoot實(shí)現(xiàn)模塊日志入庫(kù)的項(xiàng)目實(shí)踐

    SpringBoot實(shí)現(xiàn)模塊日志入庫(kù)的項(xiàng)目實(shí)踐

    本文主要介紹了SpringBoot實(shí)現(xiàn)模塊日志入庫(kù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java獲取用戶訪問(wèn)IP及地理位置的方法詳解

    Java獲取用戶訪問(wèn)IP及地理位置的方法詳解

    這篇文章主要介紹了Java獲取用戶訪問(wèn)IP及地理位置的方法,結(jié)合實(shí)例形式詳細(xì)分析了Java基于百度地圖開放平臺(tái)獲取用戶訪問(wèn)IP及地理位置相關(guān)操作技巧,需要的朋友可以參考下
    2020-04-04
  • 詳解Java中常見(jiàn)語(yǔ)法糖的使用

    詳解Java中常見(jiàn)語(yǔ)法糖的使用

    語(yǔ)法糖(Syntactic Sugar),也稱糖衣語(yǔ)法,是由英國(guó)計(jì)算機(jī)學(xué)家 Peter.J.Landin 發(fā)明的一個(gè)術(shù)語(yǔ),指在計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,本文主要為大家分享了12個(gè)java中常見(jiàn)的語(yǔ)法糖,感興趣的小伙伴可以了解下
    2023-11-11
  • Token登陸驗(yàn)證機(jī)制的原理及實(shí)現(xiàn)

    Token登陸驗(yàn)證機(jī)制的原理及實(shí)現(xiàn)

    這篇文章介紹了Token登陸驗(yàn)證機(jī)制的原理及實(shí)現(xiàn),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Java8加java10等于Java18的版本查看及特性詳解

    Java8加java10等于Java18的版本查看及特性詳解

    這篇文章主要為大家介紹了Java?8加java10等于Java18的各個(gè)版本要點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • SpringBoot中使用WebSocket的教程分享

    SpringBoot中使用WebSocket的教程分享

    這篇文章主要為大家詳細(xì)介紹了如何在SpringBoot中使用WebSocket,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06

最新評(píng)論