synchorized 幾種使用方法的比較(一)

1,併發場景不加鎖,代碼如下

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(new SynchronizedDemo());
          thread.start();
      }
  }

  @Override
  public void run() {
    
    for (int i = 0; i < 10000; i++){
      count++;
      System.out.println(Thread.currentThread().getName() + ":" + count);
    }
      
  }

結果,可以看到線程0-4沒有按照順序輸出 0-9999

Thread-0:3
Thread-4:5
Thread-4:7
Thread-4:8
Thread-4:9
Thread-4:10
Thread-3:4
Thread-2:3
result: 3
Thread-1:3
Thread-2:13
Thread-3:12
Thread-4:11
Thread-0:6
Thread-4:17
Thread-4:19
Thread-3:16
Thread-2:15
.......

2 ,採用同步方法

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(new SynchronizedDemo());
          thread.start();
      }
  }

  @Override
  public void run() {
    
      syncMthdMethod();
  }

  /**
   * 同步方法
   * */
  private synchronized void syncMthdMethod() {
    for (int i = 0; i < 10000; i++){
      count++;
      System.out.println(Thread.currentThread().getName() + ":" + count);
    }
  }
  
}

結果

Thread-2:4
Thread-2:6
Thread-2:7
Thread-2:8
Thread-4:5
Thread-4:10
Thread-3:4
Thread-3:12
Thread-3:13
Thread-3:14
Thread-3:15
Thread-3:16
......

結論,沒鎖住,因爲 每個線程 各自new了 一個SynchronizedDemo。

換個玩法

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
    SynchronizedDemo demo = new SynchronizedDemo();
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(demo);
          thread.start();
      }
  }

  @Override
  public void run() {
    
      syncMthdMethod();
  }

  /**
   * 同步方法
   * */
  private synchronized void syncMthdMethod() {
    for (int i = 0; i < 10000; i++){
      count++;
      System.out.println(Thread.currentThread().getName() + ":" + count);
    }

結果

Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17
Thread-0:18
Thread-0:19
Thread-0:20
Thread-0:21
Thread-0:22
Thread-0:23
Thread-0:24
Thread-0:25
Thread-0:26
Thread-0:27
Thread-0:28
Thread-0:29
......

結論:同步方法的鎖是對象本身,是對象本身,是對象本身!!!!

3 靜態同步方法

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(new SynchronizedDemo());
          thread.start();
      }
  }

  @Override
  public void run() {
    
    syncStaticMthdMethod();
  }
  
  /**
   * 靜態同步方法
   * */
  private static synchronized void syncStaticMthdMethod() {
    for (int i = 0; i < 10000; i++){
      count++;
      System.out.println(Thread.currentThread().getName() + ":" + count);
    }
  }
}

結果

Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17
Thread-0:18
Thread-0:19
Thread-0:20
Thread-0:21
Thread-0:22
Thread-0:23
Thread-0:24
Thread-0:25
Thread-0:26
Thread-0:27
Thread-0:28
Thread-0:29

結論 靜態同步方法的鎖對象是 類本身

4、同步代碼塊。this

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(new SynchronizedDemo());
          thread.start();
      }
  }

  @Override
  public void run() {
    
    synchronized(this){
      for (int i = 0; i < 10000; i++){
        count++;
        System.out.println(Thread.currentThread().getName() + ":" + count);
      }
    }
  }

結果沒鎖柱

Thread-2:3
Thread-0:3
Thread-1:3
Thread-3:4
Thread-1:8
Thread-0:7
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17
Thread-0:18
Thread-0:19
Thread-4:6

改一下

public static void main(String[] args) {
      SynchronizedDemo demo = new SynchronizedDemo();
      for (int i = 0; i < 5; i++) {
          Thread thread = new Thread(demo );
          thread.start();
      }
  }

結果

Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17
Thread-0:18
Thread-0:19
Thread-0:20
Thread-0:21

結論 同步代碼塊的鎖對象 this時是 對象本身

4、同步代碼塊。xxx.class

package cn.womusic.bp.batch.test.synchorized;

public class SynchronizedDemo implements Runnable {
  private static int count = 0;

  public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {
        Thread thread = new Thread(new SynchronizedDemo() );
        thread.start();
    }
}

  @Override
  public void run() {
    
    synchronized(SynchronizedDemo.class){
      for (int i = 0; i < 10000; i++){
        count++;
        System.out.println(Thread.currentThread().getName() + ":" + count);
      }
    }
  }

結果

Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17

結論 同步代碼塊的鎖對象 xxx.class時是 類本身

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章