一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - Synchronized 加鎖 This 和Class 的區別!

Synchronized 加鎖 This 和Class 的區別!

2021-08-02 22:38Java中文社群磊哥 Java教程

synchronized 是 Java 語言中處理并發問題的一種常用手段,它也被我們親切的稱之為“Java 內置鎖”,由此可見其地位之高。然而 synchronized 卻有著多種用法,當它修飾不同對象時,其意義也是不同的,下面我們一起來看。

Synchronized 加鎖 This 和Class 的區別!

synchronized 是 Java 語言中處理并發問題的一種常用手段,它也被我們親切的稱之為“Java 內置鎖”,由此可見其地位之高。然而 synchronized 卻有著多種用法,當它修飾不同對象時,其意義也是不同的,下面我們一起來看。

synchronized 用法

synchronized 可以用來修飾普通方法、靜態方法和代碼塊。

① 修飾普通方法

  1. /** 
  2.  * synchronized 修飾普通方法 
  3.  */ 
  4. public synchronized void method() { 
  5.     // ....... 

當 synchronized 修飾普通方法時,被修飾的方法被稱為同步方法,其作用范圍是整個方法,作用的對象是調用這個方法的對象。

② 修飾靜態方法

  1. /** 
  2.  * synchronized 修飾靜態方法 
  3.  */ 
  4. public static synchronized void staticMethod() { 
  5.     // ....... 

當 synchronized 修飾靜態的方法時,其作用的范圍是整個方法,作用對象是調用這個類的所有對象。

③ 修飾代碼塊

為了減少鎖的粒度,我們可以選擇在一個方法中的某個部分使用 synchronized 來修飾(一段代碼塊),從而實現對一個方法中的部分代碼進行加鎖,實現代碼如下:

  1. public void classMethod() throws InterruptedException { 
  2.     // 前置代碼... 
  3.      
  4.     // 加鎖代碼 
  5.     synchronized (SynchronizedExample.class) { 
  6.         // ...... 
  7.     } 
  8.      
  9.     // 后置代碼... 

以上代碼在執行時,被修飾的代碼塊稱為同步語句塊,其作用范圍是大括號“{}”括起來的代碼塊,作用的對象是調用這個代碼塊的對象。

但以上代碼,除了可以加鎖 class 之外,還可以加鎖 this,具體示例如下:

  1. public void classMethod() throws InterruptedException { 
  2.     // 前置處理代碼... 
  3.     synchronized (this) { 
  4.         // ...... 
  5.     } 
  6.     // 后置處理代碼... 

那問題來了,使用 synchronized 加鎖 this 和 class 的區別是什么?不都是加鎖同一個類嗎?

答案還真不是,加鎖 this 和 class 區別還是很大的。下面我們通過以下 4 個示例,來看二者之間的區別。

1.加鎖 class 共享一個類實例

首先,我們創建 5 個線程,調用同一個對象下 synchronized 加鎖的 class 代碼,具體示例如下:

  1. import java.util.Date
  2. import java.util.concurrent.TimeUnit; 
  3.  
  4. public class SynchronizedExample { 
  5.  
  6.     public static void main(String[] args) { 
  7.         // 創建當前類實例 
  8.         final SynchronizedExample example = new SynchronizedExample(); 
  9.         // 創建 5 個線程執行任務 
  10.         for (int i = 0; i < 5; i++) { 
  11.             new Thread(new Runnable() { 
  12.                 @Override 
  13.                 public void run() { 
  14.                     try { 
  15.                         // 調用 synchronized 修飾的 class 方法 
  16.                         example.classMethod(); 
  17.                     } catch (InterruptedException e) { 
  18.                         e.printStackTrace(); 
  19.                     } 
  20.                 } 
  21.             }).start(); 
  22.         } 
  23.     } 
  24.  
  25.     /** 
  26.      * synchronized 修飾的 class 方法 
  27.      * @throws InterruptedException 
  28.      */ 
  29.     public void classMethod() throws InterruptedException { 
  30.         synchronized (SynchronizedExample.class) { 
  31.             System.out.println(String.format("當前執行線程:%s,執行時間:%s"
  32.                     Thread.currentThread().getName(), new Date())); 
  33.             TimeUnit.SECONDS.sleep(1); 
  34.         } 
  35.     } 

以上程序的執行結果如下:

Synchronized 加鎖 This 和Class 的區別!

從上述結果可以看出,這 5 個線程共享的是同一把鎖。

2.加鎖 class 創建多個實例

接下來,我們創建 5 個線程,調用不同對象下 synchronized 加鎖的 class 代碼,具體示例如下:

  1. import java.util.Date
  2. import java.util.concurrent.TimeUnit; 
  3.  
  4. public class SynchronizedExample { 
  5.  
  6.     public static void main(String[] args) { 
  7.         // 創建 5 個線程執行任務 
  8.         for (int i = 0; i < 5; i++) { 
  9.             new Thread(new Runnable() { 
  10.                 @Override 
  11.                 public void run() { 
  12.                     try { 
  13.                         // 創建類實例 
  14.                         SynchronizedExample example = new SynchronizedExample(); 
  15.                         // 調用 synchronized 修飾的 class 方法 
  16.                         example.classMethod(); 
  17.                     } catch (InterruptedException e) { 
  18.                         e.printStackTrace(); 
  19.                     } 
  20.                 } 
  21.             }).start(); 
  22.         } 
  23.     } 
  24.      
  25.     /** 
  26.      * synchronized 修飾的 class 方法 
  27.      * @throws InterruptedException 
  28.      */ 
  29.     public void classMethod() throws InterruptedException { 
  30.         synchronized (SynchronizedExample.class) { 
  31.             System.out.println(String.format("當前執行線程:%s,執行時間:%s"
  32.                     Thread.currentThread().getName(), new Date())); 
  33.             TimeUnit.SECONDS.sleep(1); 
  34.         } 
  35.     } 

以上程序的執行結果如下:

Synchronized 加鎖 This 和Class 的區別!

從上述結果可以看出,雖然是不同的對象,但它們使用的仍然是同一把鎖。

3.加鎖 this 共享一個類實例

接下來,我們創建 5 個線程,調用 synchronized 加鎖 this 的示例。首先我們這 5 個線程調用同一個對象的加鎖方法,示例代碼如下:

  1. import java.util.Date
  2. import java.util.concurrent.TimeUnit; 
  3.  
  4. public class SynchronizedExample { 
  5.  
  6.     public static void main(String[] args) { 
  7.         // 創建當前類實例 
  8.         final SynchronizedExample example = new SynchronizedExample(); 
  9.         // 創建 5 個線程執行任務 
  10.         for (int i = 0; i < 5; i++) { 
  11.             new Thread(new Runnable() { 
  12.                 @Override 
  13.                 public void run() { 
  14.                     try { 
  15.                         // 調用 synchronized 修飾的 this 方法 
  16.                         example.thisMethod(); 
  17.                     } catch (InterruptedException e) { 
  18.                         e.printStackTrace(); 
  19.                     } 
  20.                 } 
  21.             }).start(); 
  22.         } 
  23.     } 
  24.      
  25.     /** 
  26.      * synchronized 修飾的 this 方法 
  27.      * @throws InterruptedException 
  28.      */ 
  29.     public void thisMethod() throws InterruptedException { 
  30.         synchronized (this) { 
  31.             System.out.println(String.format("當前執行線程:%s,執行時間:%s"
  32.                     Thread.currentThread().getName(), new Date())); 
  33.             TimeUnit.SECONDS.sleep(1); 
  34.         } 
  35.     } 

以上程序的執行結果如下:

Synchronized 加鎖 This 和Class 的區別!

從上述結果可以看出,以上線程使用的都是同一把鎖。

4.加鎖 this 創建多個類實例

最后一個示例最為特殊,我們使用 synchronized 加鎖 this,讓這 5 個線程調用各自創建對象的方法,具體示例如下:

  1. import java.util.Date
  2. import java.util.concurrent.TimeUnit; 
  3.  
  4. public class SynchronizedExample { 
  5.  
  6.     public static void main(String[] args) { 
  7.         // 創建 5 個線程執行任務 
  8.         for (int i = 0; i < 5; i++) { 
  9.             new Thread(new Runnable() { 
  10.                 @Override 
  11.                 public void run() { 
  12.                     try { 
  13.                         // 創建(多個)類實例 
  14.                         SynchronizedExample example = new SynchronizedExample(); 
  15.                         // 調用 synchronized 修飾的 this 方法 
  16.                         example.thisMethod(); 
  17.                     } catch (InterruptedException e) { 
  18.                         e.printStackTrace(); 
  19.                     } 
  20.                 } 
  21.             }).start(); 
  22.         } 
  23.     } 
  24.      
  25.     /** 
  26.      * synchronized 修飾的 this 方法 
  27.      * @throws InterruptedException 
  28.      */ 
  29.     public void thisMethod() throws InterruptedException { 
  30.         synchronized (this) { 
  31.             System.out.println(String.format("當前執行線程:%s,執行時間:%s"
  32.                     Thread.currentThread().getName(), new Date())); 
  33.             TimeUnit.SECONDS.sleep(1); 
  34.         } 
  35.     } 

以上程序的執行結果如下:

Synchronized 加鎖 This 和Class 的區別!

從上述結果可以看出,當使用 synchronized 加鎖 this 時,如果線程調用的不是同一個對象,那么這些線程之間使用的鎖都是自己獨立的鎖,這個結果就和 synchronized 加鎖 class 的結果完全不同了。

總結

通過以上 4 個示例我們可以得出結論,當使用 synchronized 加鎖 class 時,無論共享一個對象還是創建多個對象,它們用的都是同一把鎖,而使用 synchronized 加鎖 this 時,只有同一個對象會使用同一把鎖,不同對象之間的鎖是不同的。

原文鏈接:https://mp.weixin.qq.com/s/7DTk5CV5FSOsa5fSN_V26w

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人性色生活片免费网 | 18无删减羞羞网站动漫 | 精品91 | 久久人妻无码毛片A片麻豆 久久热这里只有 精品 | 色婷丁香 | 爱欲荡漾在线观看 | 爆操美女在线观看 | 欧美8x8x | 四虎影院永久网址 | 欧美伦理影院 | 狠狠鲁视频 | 日本免费v片一二三区 | 艾秋麻豆果冻剧传媒在线播放 | 色偷偷亚洲男人 | 天堂成人在线观看 | 95视频免费看片 | 亚洲琪琪| 国产一级特黄在线播放 | 大桥未久一区二区 | 国产精品伊人 | tobu8中国在线播放免费 | 人生路不在线观看完整版 | 18young第一次 | 婚前试爱免费观看 | 免费日本视频 | 99精品国产高清一区二区三区香蕉 | 黄www片| 羞羞视频麻豆 | jm漫天堂破解版 | 91国产在线视频 | 国产午夜免费秋霞影院 | 天天综合色天天综合 | 久久这里只精品国产99re66 | 日本大片免a费观看在线 | 夫承子液by免费阅读 | 999任你躁在线精品免费不卡 | 国产精品视频一区二区三区不卡 | 久久中文字幕综合不卡一二区 | 射西西| 亚洲日本va午夜中文字幕 | 欧美日韩亚洲国内综合网香蕉 |