成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Synchronized的實現原理(一)

開發 開發工具
synchronized,是Java中用于解決并發情況下數據同步訪問的一個很重要的關鍵字。當我們想要保證一個共享資源在同一時間只會被一個線程訪問到時,我們可以在代碼中使用synchronized關鍵字對類或者對象加鎖。

synchronized,是Java中用于解決并發情況下數據同步訪問的一個很重要的關鍵字。當我們想要保證一個共享資源在同一時間只會被一個線程訪問到時,我們可以在代碼中使用synchronized關鍵字對類或者對象加鎖。那么,本文來介紹一下synchronized關鍵字的實現原理是什么。在閱讀本文之間,建議先看下Java虛擬機是如何執行線程同步的 。

[[212363]]

反編譯

眾所周知,在Java中,synchronized有兩種使用形式,同步方法和同步代碼塊。代碼如下:

  1. /** 
  2.  * @author Hollis 17/11/9. 
  3.  */ 
  4. public class SynchronizedTest { 
  5.  
  6.     public synchronized void doSth(){ 
  7.         System.out.println("Hello World"); 
  8.     } 
  9.  
  10.     public void doSth1(){ 
  11.         synchronized (SynchronizedTest.class){ 
  12.             System.out.println("Hello World"); 
  13.         } 
  14.     } 

我們先來使用Javap來反編譯以上代碼,結果如下(部分無用信息過濾掉了):

  1. public synchronized void doSth(); 
  2.     descriptor: ()V 
  3.     flags: ACC_PUBLIC, ACC_SYNCHRONIZED 
  4.     Code: 
  5.       stack=2, locals=1, args_size=1 
  6.          0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream; 
  7.          3: ldc           #3                  // String Hello World 
  8.          5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
  9.          8: return 
  10.  
  11.   public void doSth1(); 
  12.     descriptor: ()V 
  13.     flags: ACC_PUBLIC 
  14.     Code: 
  15.       stack=2, locals=3, args_size=1 
  16.          0: ldc           #5                  // class com/hollis/SynchronizedTest 
  17.          2: dup 
  18.          3: astore_1 
  19.          4: monitorenter 
  20.          5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream; 
  21.          8: ldc           #3                  // String Hello World 
  22.         10: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
  23.         13: aload_1 
  24.         14: monitorexit 
  25.         15: goto          23 
  26.         18: astore_2 
  27.         19: aload_1 
  28.         20: monitorexit 
  29.         21: aload_2 
  30.         22: athrow 
  31.         23: return 

反編譯后,我們可以看到Java編譯器為我們生成的字節碼。在對于doSth和doSth1的處理上稍有不同。也就是說。JVM對于同步方法和同步代碼塊的處理方式不同。

對于同步方法,JVM采用ACC_SYNCHRONIZED標記符來實現同步。 對于同步代碼塊。JVM采用monitorenter、monitorexit兩個指令來實現同步。

關于這部分內容,在JVM規范中也可以找到相關的描述。

同步方法

The Java? Virtual Machine Specification中有關于方法級同步的介紹:

Method-level synchronization is performed implicitly, as part of method invocation and return. A synchronized method is distinguished in the run-time constant pool's methodinfo structure by the ACCSYNCHRONIZED flag, which is checked by the method invocation instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.

主要說的是: 方法級的同步是隱式的。同步方法的常量池中會有一個ACC_SYNCHRONIZED標志。當某個線程要訪問某個方法的時候,會檢查是否有ACC_SYNCHRONIZED,如果有設置,則需要先獲得監視器鎖,然后開始執行方法,方法執行之后再釋放監視器鎖。這時如果其他線程來請求執行方法,會因為無法獲得監視器鎖而被阻斷住。值得注意的是,如果在方法執行過程中,發生了異常,并且方法內部并沒有處理該異常,那么在異常被拋到方法外面之前監視器鎖會被自動釋放。

同步代碼塊

同步代碼塊使用monitorenter和monitorexit兩個指令實現。 The Java? Virtual Machine Specification 中有關于這兩個指令的介紹:

monitorenter

Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:

If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.

If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.

If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.

monitorexit

The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.

The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

大致內容如下: 可以把執行monitorenter指令理解為加鎖,執行monitorexit理解為釋放鎖。 每個對象維護著一個記錄著被鎖次數的計數器。未被鎖定的對象的該計數器為0,當一個線程獲得鎖(執行monitorenter)后,該計數器自增變為 1 ,當同一個線程再次獲得該對象的鎖的時候,計數器再次自增。當同一個線程釋放鎖(執行monitorexit指令)的時候,計數器再自減。當計數器為0的時候。鎖將被釋放,其他線程便可以獲得鎖。

總結

同步方法通過ACC_SYNCHRONIZED關鍵字隱式的對方法進行加鎖。當線程要執行的方法被標注上ACC_SYNCHRONIZED時,需要先獲得鎖才能執行該方法。

同步代碼塊通過monitorenter和monitorexit執行來進行加鎖。當線程執行到monitorenter的時候要先獲得所鎖,才能執行后面的方法。當線程執行到monitorexit的時候則要釋放鎖。

每個對象自身維護這一個被加鎖次數的計數器,當計數器數字為0時表示可以被任意線程獲得鎖。當計數器不為0時,只有獲得鎖的線程才能再次獲得鎖。即可重入鎖。

至此,我們大致了解了Synchronized的原理。但是還有幾個問題并沒有介紹清楚,比如,Monitor到底是什么?對象的鎖的狀態保存在哪里? 別急,后面會再介紹。

【本文是51CTO專欄作者Hollis的原創文章,作者微信公眾號Hollis(ID:hollischuang)】

戳這里,看該作者更多好文

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2021-01-08 08:34:09

Synchronize線程開發技術

2025-03-20 06:48:55

性能優化JDK

2022-12-26 09:27:48

Java底層monitor

2020-08-23 10:03:51

SynchronizeJava

2021-07-04 08:01:30

Synchronize線程安全并發編程

2017-02-27 10:43:07

Javasynchronize

2024-03-15 15:12:27

關鍵字底層代碼

2024-03-07 07:47:04

代碼塊Monitor

2022-04-13 14:43:05

JVM同步鎖Monitor 監視

2021-03-04 08:26:17

synchronizeReentrantLojava

2019-05-27 08:11:13

高并發Synchronize底層

2015-12-02 14:10:56

HTTP網絡協議代理原理

2024-12-17 08:28:30

2022-10-28 10:23:27

Java多線程底層

2020-11-02 08:54:29

JMMVolatileSynchronize

2024-08-28 08:00:00

2021-05-14 16:34:12

Semaphore原理

2017-09-18 09:03:36

線程安全單例

2021-01-14 08:58:12

Synchronize鎖操作

2024-03-13 08:34:22

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩免费视频一区二区 | 欧美xxxx性xxxxx高清 | 91av在线视频观看 | 国产大毛片| 一区欧美 | 欧美日韩三级 | 热re99久久精品国99热观看 | 亚洲电影免费 | 日韩av在线一区 | 天天综合国产 | 欧美亚洲国产日韩 | 日韩免费一区二区 | 日韩在线观看一区 | 久久综合av | 成人h视频| 狠狠躁躁夜夜躁波多野结依 | 欧美一级淫片免费视频黄 | 中文字幕国产视频 | 久久国产婷婷国产香蕉 | 精品国产91乱码一区二区三区 | 精品综合 | 91最新在线视频 | 久在线观看| 国产精品日日夜夜 | 精品久久久久久亚洲精品 | 成人免费区一区二区三区 | 超碰男人天堂 | 欧美一区二区三区在线观看 | 国产成人精品久久久 | 女人毛片a毛片久久人人 | 国产精品高潮呻吟久久aⅴ码 | 日本视频中文字幕 | 亚洲区一区二 | 一区二区三区小视频 | 一区二区三区四区在线 | 久久精品国产亚洲夜色av网站 | 日韩视频在线免费观看 | 亚洲视频www | 日本亚洲欧美 | 日韩中文字幕在线观看 | 国产福利在线视频 |