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

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java多線程并發編程 Synchronized關鍵字

Java多線程并發編程 Synchronized關鍵字

2020-10-23 20:59mdxy-dxy Java教程

現有一成員變量 Test,當線程 A 調用 Test 的 synchronized 方法,線程 A 獲得 Test 的同步鎖,同時,線程 B 也去調用 Test 的 synchronized 方法,此時線程 B 無法獲得 Test 的同步鎖,必須等待線程 A 釋放 Test 的同步鎖才能獲得從而執行對應方

synchronized 關鍵字解析

同步鎖依賴于對象,每個對象都有一個同步鎖。

現有一成員變量 Test,當線程 A 調用 Test 的 synchronized 方法,線程 A 獲得 Test 的同步鎖,同時,線程 B 也去調用 Test 的 synchronized 方法,此時線程 B 無法獲得 Test 的同步鎖,必須等待線程 A 釋放 Test 的同步鎖才能獲得從而執行對應方法的代碼。

綜上,正確使用 synchronized 關鍵字可確保原子性。

synchronized 關鍵字的特性應用

特性 1:

當線程 A 調用某對象的synchronized 方法 或者 synchronized 代碼塊時,若同步鎖未釋放,其他線程調用同一對象的synchronized 方法 或者 synchronized 代碼塊時將被阻塞,直至線程 A 釋放該對象的同步鎖。

DEMO1,synchronized 方法:

?
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
public class Test {
 
  private static class Counter {
 
    public synchronized void count() {
      for (int i = 0; i < 6; i++) {
        System.out.println(Thread.currentThread().getName() + ", i = " + i);
      }
    }
 
  }
 
  private static class MyThread extends Thread {
 
    private Counter mCounter;
 
    public MyThread(Counter counter) {
      mCounter = counter;
    }
 
    @Override
    public void run() {
      super.run();
      mCounter.count();
    }
  }
 
  public static void main(String[] var0) {
    Counter counter = new Counter();
    // 注:myThread1 和 myThread2 是調用同一個對象 counter
    MyThread myThread1 = new MyThread(counter);
    MyThread myThread2 = new MyThread(counter);
    myThread1.start();
    myThread2.start();
  }
 
}

DEMO1 輸出:

?
1
2
3
4
5
6
7
8
9
10
11
12
Thread-0, i = 0
Thread-0, i = 1
Thread-0, i = 2
Thread-0, i = 3
Thread-0, i = 4
Thread-0, i = 5
Thread-1, i = 0
Thread-1, i = 1
Thread-1, i = 2
Thread-1, i = 3
Thread-1, i = 4
Thread-1, i = 5

DEMO2,synchronized 代碼塊:

?
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
public class Test {
 
  private static class Counter {
 
    public void count() {
      synchronized (this) {
        for (int i = 0; i < 6; i++) {
          System.out.println(Thread.currentThread().getName() + ", i = " + i);
        }
      }
    }
  }
 
  private static class MyThread extends Thread {
 
    private Counter mCounter;
 
    public MyThread(Counter counter) {
      mCounter = counter;
    }
 
    @Override
    public void run() {
      super.run();
      mCounter.count();
    }
  }
 
  public static void main(String[] var0) {
    Counter counter = new Counter();
    MyThread myThread1 = new MyThread(counter);
    MyThread myThread2 = new MyThread(counter);
    myThread1.start();
    myThread2.start();
  }
}

DEMO2 輸出:

?
1
2
3
4
5
6
7
8
9
10
11
12
Thread-0, i = 0
Thread-0, i = 1
Thread-0, i = 2
Thread-0, i = 3
Thread-0, i = 4
Thread-0, i = 5
Thread-1, i = 0
Thread-1, i = 1
Thread-1, i = 2
Thread-1, i = 3
Thread-1, i = 4
Thread-1, i = 5

可見,當同步鎖未釋放時,其他線程將被阻塞,直至獲得同步鎖。

而且 DEMO1 和 DEMO2 的輸出結果是一樣的,synchronized 方法 和 synchronized 代碼塊的不同之處在于 synchronized 方法 作用域較大,作用于整個方法,而 synchronized 代碼塊 可控制具體的作用域,更精準控制提高效率。(畢竟阻塞的都是時間啊)

DEMO3,僅修改 main 方法:

?
1
2
3
4
5
6
7
public static void main(String[] var0) {
    // 注意:myThread1 和 myThread2 傳入的 Counter 是兩個不同的對象
    MyThread myThread1 = new MyThread(new Counter());
    MyThread myThread2 = new MyThread(new Counter());
    myThread1.start();
    myThread2.start();
  }

DEMO3 輸出:

?
1
2
3
4
5
6
7
8
9
10
11
12
Thread-0, i = 0
Thread-1, i = 0
Thread-0, i = 1
Thread-1, i = 1
Thread-1, i = 2
Thread-1, i = 3
Thread-0, i = 2
Thread-1, i = 4
Thread-0, i = 3
Thread-1, i = 5
Thread-0, i = 4
Thread-0, i = 5

同步鎖基于對象,只要鎖的來源一致,即可達到同步的作用。所以,但對象不一樣,則不能達到同步效果。

特性 2:

當線程 A 調用某對象的synchronized 方法 或者 synchronized 代碼塊時,若同步鎖未釋放,其他線程調用同一對象的其他 synchronized 方法 或者 synchronized 代碼塊時將被阻塞,直至線程 A 釋放該對象的同步鎖。(注意:重點是其他)

DEMO4,僅修改 doOtherThings 方法的修飾:

?
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
public class Test {
 
  private static class Counter {
 
    public synchronized void count() {
      System.out.println(Thread.currentThread().getName() + " sleep");
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " awake");
    }
 
    public synchronized void doOtherThings(){
      System.out.println(Thread.currentThread().getName() + " doOtherThings");
    }
  }
 
  public static void main(String[] var0) {
    final Counter counter = new Counter();
    new Thread(new Runnable() {
      @Override
      public void run() {
        counter.count();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        counter.doOtherThings();
      }
    }).start();
  }
}

DEMO4 輸出:

?
1
2
3
Thread-0 sleep
Thread-0 awake
Thread-1 doOtherThings

可見,synchronized 獲得的同步鎖并非僅僅鎖住代碼,而是鎖住整個對象。

此時應提及 happens-before 原則,正因 happens-before 原則的存在才有此現象的發生。
happens-before 原則的其中一條:
管理鎖定原則:一個 unLock 操作先行發生于后面對同一個鎖的 lock 操作。
(此處暫不作過多解釋,解釋起來能再寫一篇文章了)

DEMO5,僅修改 doOtherThings 方法:

?
1
2
3
4
5
public void doOtherThings(){
      synchronized (this){
        System.out.println(Thread.currentThread().getName() + " doOtherThings");
      }
    }

DEMO5 輸出:

?
1
2
3
Thread-0 sleep
Thread-0 awake
Thread-1 doOtherThings

DEMO4 和 DEMO5 的輸出結果竟然一致!沒錯,因為他們的同步鎖來源一致(都是本實例自己),所以可以達到同步效果。

?
1
2
3
4
5
// 這兩個 synchronized 鎖的是同一個對象
public synchronized void count(){};
public void doOtherThings(){
    synchronized (this){}
}

DEMO6,去掉 doOtherThings 方法的同步關鍵字:

?
1
2
3
public void doOtherThings(){
      System.out.println(Thread.currentThread().getName() + " doOtherThings");
    }

DEMO6 輸出:

?
1
2
3
Thread-0 sleep
Thread-1 doOtherThings
Thread-0 awake

當線程 A 調用某對象的synchronized 方法 或者 synchronized 代碼塊時,無論同步鎖是否釋放,其他線程調用同一對象的其他 非 synchronized 方法 或者 非 synchronized 代碼塊時可立即調用。

實例鎖和全局鎖

以上 DEMO 實現的都是實例鎖。鎖住(作用域)的是具體某一對象實例。

什么是全局鎖?
鎖住整個 Class,而非某個對象或實例。

注:單例型的實例鎖不屬于全局鎖。

全局鎖的實現:

靜態 synchronized 方法

DEMO7:

?
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
public class Test {
 
  private static class Counter {
 
    public static synchronized void count() {
      System.out.println(Thread.currentThread().getName() + " sleep");
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " awake");
    }
 
    public static synchronized void doOtherThings(){
      System.out.println(Thread.currentThread().getName() + " doOtherThings");
    }
  }
 
  public static void main(String[] var0) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        Counter.count();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        Counter.doOtherThings();
      }
    }).start();
  }
}

DEMO7 輸出:

?
1
2
3
Thread-0 sleep
Thread-0 awake
Thread-1 doOtherThings

static 聲明的方法為全局方法,與對象實例化無關,所以 static synchronized 方法為全局同步方法,與對象實例化無關。

synchronized 具體 Class 的代碼塊

DEMO8:

?
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
public class Test {
 
  private static class Counter {
 
    public static synchronized void count() {
      System.out.println(Thread.currentThread().getName() + " sleep");
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " awake");
    }
 
    public void doOtherThings(){
      synchronized (Counter.class){
        System.out.println(Thread.currentThread().getName() + " doOtherThings");
      }
    }
  }
 
  public static void main(String[] var0) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        Counter.count();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        Counter counter = new Counter();
        counter.doOtherThings();
      }
    }).start();
  }
}

DEMO8 輸出:

?
1
2
3
Thread-0 sleep
Thread-0 awake
Thread-1 doOtherThings

synchronized (Counter.class) 獲得的同步鎖是全局的,static synchronized 獲得的同步鎖也是全局的,同一個鎖,所以達到同步效果。

區分 synchronized (this) 與 synchronized (Class.class)

DEMO9:

?
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
public class Test {
 
  private static class Counter {
 
    public void count() {
      synchronized (this){
        System.out.println(Thread.currentThread().getName() + " sleep");
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " awake");
      }
    }
 
    public void doOtherThings(){
      synchronized (Counter.class){
        System.out.println(Thread.currentThread().getName() + " doOtherThings");
      }
    }
  }
 
  public static void main(String[] var0) {
    final Counter counter = new Counter();
    new Thread(new Runnable() {
      @Override
      public void run() {
        counter.count();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        counter.doOtherThings();
      }
    }).start();
  }
}

DEMO9 輸出:

?
1
2
3
Thread-0 sleep
Thread-1 doOtherThings
Thread-0 awake

synchronized (this) 獲得的是具體對象實例 counter 的鎖,而 synchronized (Counter.class) 獲得的是全局鎖,兩把不同的鎖,所以不能達到同步效果。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩欧美精品一区二区三区 | 美足av| 国产精品久久久久久久久免费桃花 | 欧美一区二区三区在线观看视频 | 国产又色又爽又黄又免费 | 亚洲精品综合 | 美女黄网 | 欧美性久久 | 免费一级性片 | 日韩激情免费视频 | 毛片av在线播放 | 免费一级视频在线观看 | 日日操天天爽 | 成人爽a毛片一区二区免费 日韩av高清在线 | 超碰成人在线免费 | 久久久高清 | 欧美一区二区网站 | 亚洲精品久久久久久国产精华液 | 久久99国产精一区二区三区 | 天堂va在线高清一区 | 麻豆产精国品免费 | 成人午夜电影在线观看 | 成人网在线观看 | 97久久精品 | 日韩国产一区二区三区 | 日韩电影一区 | 久久久久久久成人 | 午夜午夜精品一区二区三区文 | 欧美美女爱爱 | 久久99精品视频 | 中文字幕视频在线观看 | av电影免费观看 | 日韩国产一区二区三区 | 欧美自拍网 | 国内精品一级毛片国产99 | 在线国产日韩 | 综合伊人| 久久男女| 国产精品区二区三区日本 | av片在线观看 | 99久久精品免费看国产一区二区三区 |