国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - 詳解java中的synchronized關(guān)鍵字

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

2020-03-06 20:02Gang.Wang JAVA教程

這篇文章主要介紹了java中的synchronized關(guān)鍵字,可用來給對(duì)象和方法或者代碼塊加鎖,當(dāng)它鎖定一個(gè)方法或者一個(gè)代碼塊的時(shí)候,同一時(shí)刻最多只有一個(gè)線程執(zhí)行這段代碼,感興趣的小伙伴們可以參考一下

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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è)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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è)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

修改Thread2.m4t2()方法:     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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è)例子同樣適用其它同步代碼塊。也就是說,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問都被暫時(shí)阻塞。

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

?
1
2
3
4
5
6
7
8
9
10
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ì)象鎖同樣適用:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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訪問的是同一個(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:

?
1
2
3
4
5
6
7
8
9
10
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訪問了同一個(gè)Inner對(duì)象中兩個(gè)毫不相關(guān)的部分,但因?yàn)閠1先獲得了對(duì)Inner的對(duì)象鎖,所以t2對(duì)Inner.m4t2()的訪問也被阻塞,因?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 方法:通過在方法聲明中加入 synchronized關(guān)鍵字來聲明 synchronized 方法。如: 
public synchronized void accessVal(int newVal); 
synchronized 方法控制對(duì)類成員變量的訪問:每個(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)的鎖),從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變量的方法均被聲明為 synchronized)。 
在 Java 中,不光是類實(shí)例,每一個(gè)類也對(duì)應(yīng)一把鎖,這樣我們也可將類的靜態(tài)成員函數(shù)聲明為 synchronized ,以控制其對(duì)類的靜態(tài)成員變量的訪問。 
synchronized 方法的缺陷:若將一個(gè)大的方法聲明為synchronized 將會(huì)大大影響效率,典型地,若將線程類的方法 run() 聲明為synchronized ,由于在線程的整個(gè)生命期內(nèi)它一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類任何 synchronized 方法的調(diào)用都永遠(yuǎn)不會(huì)成功。當(dāng)然我們可以通過將訪問類成員變量的代碼放到專門的方法中,將其聲明為 synchronized ,并在主方法中調(diào)用來解決這一問題,但是 Java 為我們提供了更好的解決辦法,那就是 synchronized 塊。 
2. synchronized 塊:通過 synchronized關(guān)鍵字來聲明synchronized 塊。語法如下: 
synchronized(syncObject) { 
//允許訪問控制的代碼 

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

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

延伸 · 閱讀

精彩推薦
529
主站蜘蛛池模板: 中文字幕亚洲一区二区va在线 | 最新日韩免费 | 国产美女视频网站 | 成人国产精品视频 | 亚洲专区 变态 另类 | 99精品欧美一区二区蜜桃免费 | 成人久久久 | 欧美大成色www永久网站婷 | 日韩三级电影在线免费观看 | 中文字幕av亚洲精品一部二部 | 国产99久久 | 高清三区 | 日本中文字幕在线免费观看 | 69久久久| 国产精品美女久久久av超清 | 国产丝袜久久久 | 中文字幕亚洲欧美日韩在线不卡 | 欧美一区永久视频免费观看 | 999久久久国产999久久久 | 亚洲一区在线免费观看 | 欧美精品一区自拍a毛片在线视频 | 日韩在线观看中文字幕 | 中文字幕观看 | 亚洲a网| 色综合色综合 | 97爱爱爱| 成人av在线播放 | 亚洲综合首页 | 成人自拍视频 | 国产精品欧美一区二区三区不卡 | 国产精品日本一区二区不卡视频 | 一区二区三区四区视频 | 免费观看一级视频 | 亚洲毛片网站 | 91免费精品 | 在线国产一区 | 九九九九精品九九九九 | 国产高清自拍视频 | 精品一区二区精品 | 国产精品久久久 | 黄在线免费 |