最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程中synchronized的用法與原理解析

 更新時(shí)間:2024年01月29日 10:36:43   作者:Smallc0de  
這篇文章主要介紹了Java線程中synchronized的用法與原理解析,只要有線程,就會(huì)有并發(fā)的現(xiàn)象,也同時(shí)會(huì)產(chǎn)生數(shù)據(jù)不一致,那么對(duì)于需要使用同一個(gè)數(shù)據(jù)的兩個(gè)線程,就會(huì)產(chǎn)生沖突,那么就引出了鎖的概念,本篇會(huì)針對(duì)性的說下synchronized這個(gè)關(guān)鍵字,需要的朋友可以參考下

前言

說到Java就必然會(huì)考慮到線程的問題,無(wú)論工作中學(xué)習(xí)中有沒有直接接觸過多線程開發(fā),手寫過線程調(diào)用,在這個(gè)底層已經(jīng)到了多核多緩存的硬件時(shí)代,多線程是任何碼農(nóng)都繞不過的一個(gè)事情。只要有線程,就會(huì)有并發(fā)的現(xiàn)象,也同時(shí)會(huì)產(chǎn)生數(shù)據(jù)不一致。那么對(duì)于需要使用同一個(gè)數(shù)據(jù)的兩個(gè)線程,就會(huì)產(chǎn)生沖突,那么就引出了鎖的概念。鎖有很多種本篇會(huì)針對(duì)性的說下synchronized這個(gè)關(guān)鍵字是如何保證線程的有序進(jìn)行。

現(xiàn)實(shí)場(chǎng)景

能用到多線程的場(chǎng)景有很多,比如餐館叫號(hào),醫(yī)院掛號(hào),銀行辦理業(yè)務(wù)等等數(shù)不勝數(shù)。最近春運(yùn)要到了,就以買火車票為例子?,F(xiàn)在有5個(gè)人買北京站買車票,一共有三個(gè)窗口,于是5個(gè)人去車站買票。車票么一張票對(duì)應(yīng)一個(gè)座兒,誰(shuí)買了誰(shuí)坐,這個(gè)大家都明白。但是如果沒有任何的限制,大概會(huì)有下面幾個(gè)可能:

  • 重號(hào):有三個(gè)人同時(shí)去買北京到上海的票,于是三個(gè)售票員同時(shí)發(fā)現(xiàn)系統(tǒng)顯示某車廂里1號(hào)座位可以賣,于是三個(gè)售票員同時(shí)給了三個(gè)人這個(gè)車廂的1號(hào)座票,這三張一樣票誰(shuí)用就成了麻煩,這就是重號(hào)。
  • 錯(cuò)號(hào):有兩個(gè)人同時(shí)去買票,售票員應(yīng)該賣出北京到上海給乘客1,應(yīng)該賣出北京到成都給乘客2,于是按照這樣的{北京上海、北京成都}的順序提交了訂單到系統(tǒng)。但是付錢的時(shí)候乘客2單身久了手比較快先付了錢,結(jié)果把{北京上海}的票給買到了,沒辦法去成都了,這個(gè)就是系統(tǒng)發(fā)生了錯(cuò)號(hào)。
  • 跳號(hào):跳號(hào)和錯(cuò)號(hào)發(fā)生的場(chǎng)景差不多。網(wǎng)點(diǎn)升級(jí)現(xiàn)在有50個(gè)窗口,一共有兩百?gòu)埰笨梢再u對(duì)應(yīng)訂單號(hào)1-200,但是有400位乘客同時(shí)去買。結(jié)果訂單號(hào)生成的順序亂七八糟,而且超過200的訂單號(hào)都有可能,這種情況發(fā)生就叫做跳號(hào)。

這種問題在日常生活中是無(wú)法容忍的,因此必須使得某些變量在整個(gè)系統(tǒng)中是唯一,并且是線程共享的,因此java中就有了關(guān)鍵字static。但是static雖然可以保證唯一性,但是無(wú)法解決上面的三個(gè)問題,尤其是并發(fā)量比較大的時(shí)候。

問題分析

這種問題是如何發(fā)生的呢?簡(jiǎn)單來(lái)說就是前一個(gè)線程拿到數(shù)據(jù)做了修改,但是還沒有輸出就被第二個(gè)線程拿取用了。

比如下圖,本來(lái)應(yīng)該輸出101的Thread1,經(jīng)過Thread2的競(jìng)爭(zhēng)輸出了102,這就是為什么產(chǎn)生了重號(hào),跳號(hào),錯(cuò)號(hào)等等這些問題的原因。

總結(jié)來(lái)說多線程會(huì)導(dǎo)致數(shù)據(jù)不一致問題。

在這里插入圖片描述

解決問題

導(dǎo)致這個(gè)問題的根本原因在哪呢?就是number++這個(gè)操作,這個(gè)操作并不是一個(gè)原子操作。

它可以被拆分為三步:

1.讀取number;

2.number+1;

3.回寫主存。

這些步驟都走完了才會(huì)輪到輸出。所以number++和輸出應(yīng)該是一個(gè)業(yè)務(wù)邏輯內(nèi)的事情,也就是說在邏輯上應(yīng)該是具有原子性的,不可分割的。

如何對(duì)這一塊邏輯進(jìn)行封鎖呢?Java里可以使用synchronized關(guān)鍵字,當(dāng)然也可以使用lock,但是本篇的主角不是lock。

//比如我們可以把當(dāng)前對(duì)象鎖起來(lái)。
synchronized (this){
    while(number<100){
        System.out.println("本次的號(hào)碼是:"+number++);
    }
}

這樣鎖起來(lái)以后,在執(zhí)行while循環(huán)的時(shí)候,就不會(huì)在允許其他線程去干擾這部分執(zhí)行,要么執(zhí)行完,要么都不執(zhí)行。當(dāng)整個(gè)while的內(nèi)容有了不可分割的屬性以后,它就具有了原子性。

根據(jù)這個(gè)邏輯,當(dāng)Thread1占有資源時(shí),Thread2只能等待Thread1中synchronized塊里的內(nèi)容運(yùn)行完畢以后,才可以獲取資源,以此類推。

在這里插入圖片描述

synchronized 的鎖機(jī)制

上面的解決辦法,就是利用了synchronized鎖機(jī)制去實(shí)現(xiàn)數(shù)據(jù)同步的,從而保證了數(shù)據(jù)的一致性。從上面的例子來(lái)看,鎖機(jī)制大概有兩種特性:

  • 排他性:也叫做互斥性、獨(dú)占性,即在同一時(shí)間只允許一個(gè)線程持有某個(gè)對(duì)象鎖,通過這種特性來(lái)實(shí)現(xiàn)多線程中的協(xié)調(diào)機(jī)制,這樣在同一時(shí)間只有一個(gè)線程對(duì)需同步的代碼塊(復(fù)合操作)進(jìn)行訪問。排他性我們也往往稱為操作的原子性。
  • 可見性:必須確保在鎖被釋放之前,對(duì)共享變量所做的修改,對(duì)于隨后獲得該鎖的另一個(gè)線程是可見的(即在獲得鎖時(shí)應(yīng)獲得最新共享變量的值),否則另一個(gè)線程可能是在本地緩存的某個(gè)副本上繼續(xù)操作從而引起不一致。比如:t1修改了number為101,t2要知道number被修改了,才能對(duì)number操作繼續(xù)修改為102。

synchronized 的用法

synchronized 的用法很簡(jiǎn)單,大概分為兩種??梢愿鶕?jù)修飾對(duì)象分類,也可以根據(jù)獲取的鎖分類。

根據(jù)修飾對(duì)象分類:

synchronized關(guān)鍵字修飾在方法上

*****synchronized 可以加在非靜態(tài)方法上*****
public synchronized void methodName(){
    // code ......
}
*****synchronized 可以加在靜態(tài)方法上*****
public synchronized static void methodName(){
    // code ......
}

synchronized關(guān)鍵字修飾代碼塊

*****synchronized 可以加在某個(gè)對(duì)象上*****
public void methodName3(){
    synchronized (this){ //這里可以寫任意對(duì)象,此時(shí)是當(dāng)前對(duì)象
        // code ......
    }
}
//也可以是任意對(duì)象。但是這個(gè)對(duì)象必須是final的,因?yàn)椴煌木€程會(huì)創(chuàng)建不同的對(duì)象,也就會(huì)鎖住不同的變量,因此這里就會(huì)出現(xiàn)不一致問題。
private final Object object =new Object();
public void methodName4(){
    synchronized (object){
        // code ......
    }
}
*****synchronized 可以加在某個(gè)類上*****
public void methodName5(){
    synchronized (SynTest.class){
        // code ......
    }
}

根據(jù)獲取的鎖分類:

獲取對(duì)象鎖

//就是再說下面兩種修飾方法:
synchronized(this|object) {}  //加在對(duì)象上
synchronized 修飾非靜態(tài)方法

在 Java 中,每個(gè)對(duì)象都會(huì)有一個(gè) monitor 對(duì)象,這個(gè)對(duì)象其實(shí)就是 Java 對(duì)象的鎖,通常會(huì)被稱為“內(nèi)置鎖”或“對(duì)象鎖”。類的對(duì)象可以有多個(gè),所以每個(gè)對(duì)象有其獨(dú)立的對(duì)象鎖,互不干擾。

但是一旦引用類型加上final就變味了,final修飾引用類型后,在對(duì)其初始化之后便不能再讓其指向其他對(duì)象了,但該引用所指向的對(duì)象的內(nèi)容是可以發(fā)生變化的。這也是為什么上面說對(duì)象必須是final的。

獲取類鎖

//就是再說下面兩種修飾方法:
synchronized(ClassName.class) {} //加在類上
synchronized 修飾靜態(tài)方法

在 Java 中,針對(duì)每個(gè)類也有一個(gè)鎖,可以稱為“類鎖”,類鎖實(shí)際上是通過對(duì)象鎖實(shí)現(xiàn)的,即類的 Class 對(duì)象鎖。當(dāng)ClassLoader把class文件加載到方法區(qū)的時(shí)候,會(huì)在堆區(qū)生產(chǎn)一個(gè)Class對(duì)象,每個(gè)類只有一個(gè) Class 對(duì)象,因此某個(gè)類的所有對(duì)象會(huì)共享同一個(gè)Class對(duì)象。正是由于使用的是同一個(gè)Class對(duì)象,該類所有對(duì)象都會(huì)被synchronized所限制,所以每個(gè)類只有一個(gè)類鎖。

synchronized 代碼塊堆棧分析

為了明白synchronized的運(yùn)行原理,首先先看下synchronized關(guān)鍵字在運(yùn)行時(shí)的表現(xiàn),有這么一段小程序作為測(cè)試程序。

public class SyncTest {
    public void method(){
        synchronized(this){
            try {
                TimeUnit.MINUTES.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" has started");
        }
    }
    public static void main(String[] args) {
        SyncTest test=new SyncTest();
        for (int i = 0; i <5 ; i++) {
            new Thread(test::method).start();
        }
    }
}

使用cmd調(diào)出控制臺(tái),鍵入jps命令顯示當(dāng)前運(yùn)行的java線程。

在這里插入圖片描述

找到正在運(yùn)行的SyncTest線程id:25784,然后鍵入jstack 25784,查看線程運(yùn)行狀況。可以看到Thread-1到Thread-4都被阻塞了,只有Thread-0 處于time wait狀態(tài),那么就是說明synchronized確實(shí)做到了排他性,一旦一個(gè)線程占用了某資源,其他線程執(zhí)行等待資源。也正是這種狀態(tài),最終我們能夠?qū)崿F(xiàn)同步。

在這里插入圖片描述

synchronized 代碼塊實(shí)現(xiàn)原理

synchronized到底底層是怎么實(shí)現(xiàn)的呢?接下來(lái)就必須通過jvm的反編譯指令進(jìn)行一個(gè)分析,使用方法在最后附錄里。

所以我們找到SyncTest.class文件,使用javap –v SyncTest命令就可以把這個(gè)class文件的附加信息都拿出來(lái)。

那么我們從解析的反編譯文件里找到method()方法:

public void method();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=4, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter		***** monitorenter互斥的入口
         4: getstatic     #2                  // Field java/util/concurrent/TimeUnit.MINUTES:Ljava/util/concurrent/TimeUnit;
         7: ldc2_w        #3                  // long 10l
        10: invokevirtual #5                  // Method java/util/concurrent/TimeUnit.sleep:(J)V
        13: goto          21
        16: astore_2
        17: aload_2
        18: invokevirtual #7                  // Method java/lang/InterruptedException.printStackTrace:()V
        21: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
        24: new           #9                  // class java/lang/StringBuilder
        27: dup
        28: invokespecial #10                 // Method java/lang/StringBuilder."<init>":()V
        31: invokestatic  #11                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
        34: invokevirtual #12                 // Method java/lang/Thread.getName:()Ljava/lang/String;
        37: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        40: ldc           #14                 // String  has started
        42: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        45: invokevirtual #15                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        48: invokevirtual #16                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        51: aload_1
        52: monitorexit		***** 一直到這里退出,可以算作互斥的出口
        53: goto          61
        56: astore_3
        57: aload_1
        58: monitorexit		***** 發(fā)現(xiàn)還有一個(gè)monitorexit,這個(gè)是異常出口,下面有解釋
        59: aload_3
        60: athrow
        61: return

從反編譯的文件結(jié)合上述我們已經(jīng)說過的鎖機(jī)制,很顯然匯編代碼中monitorenter就是互斥的入口,然后直到下面第52行執(zhí)行monitorexit退出。在此期間執(zhí)行的命令其他線程就無(wú)法操作了,這就是所謂的鎖(Lock),所以鎖(Lock)鎖住的是什么呢?鎖住的就是從第3行到第52行之間的內(nèi)容,那么整個(gè)從monitorenter開始到monitorexit退出就是我們常說的鎖的原理。

這也解釋了為什么synchronized塊要加在一個(gè)對(duì)象上或者需要加在一個(gè)class上,因?yàn)閟ynchronized關(guān)鍵字需要和class文件也就是對(duì)象或者類相關(guān)聯(lián),synchronized塊就是提供這樣一個(gè)monitorenter標(biāo)記給相應(yīng)的class文件,因此需要加上一個(gè)對(duì)象或者類作為標(biāo)記。

除此以外還有一個(gè)小要點(diǎn):繼續(xù)往下走,發(fā)現(xiàn)第58行還有一個(gè)monitorexit標(biāo)記,為什么一個(gè)入口要有兩個(gè)出口呢?

因?yàn)榈谝粋€(gè)出口是正常出口,程序執(zhí)行無(wú)誤就從第52行正常退出;如果程序執(zhí)行發(fā)生異常,無(wú)法執(zhí)行到第52行的出口,就從第58行的出口退出。

synchronized 作為方法關(guān)鍵字

上面說完synchronized塊是如何做到的鎖,下面我們看看synchronized作為方法關(guān)鍵字的時(shí)候會(huì)不會(huì)還是一樣的,首先添加下面這樣一個(gè)方法到測(cè)試程序中:

public static synchronized void methodName(){
    while(number<100){
        System.out.println("本次的號(hào)碼是:"+number++);
    }
}

然后如法炮制,運(yùn)行javap –v SyncTest命令。

 public static synchronized void methodName();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED		*方法標(biāo)記
    Code:
      stack=5, locals=0, args_size=0
         0: getstatic     #15                 // Field number:I
         3: bipush        100
         5: if_icmpge     44
         8: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        11: new           #7                  // class java/lang/StringBuilder
        14: dup
        15: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
        18: ldc           #16                 // String 本次的號(hào)碼是:
        20: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        23: getstatic     #15                 // Field number:I
        26: dup
        27: iconst_1
        28: iadd
        29: putstatic     #15                 // Field number:I
        32: invokevirtual #17                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        35: invokevirtual #13                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        38: invokevirtual #14                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        41: goto          0
        44: return
      LineNumberTable:
        line 19: 0
        line 20: 8
        line 22: 44
      StackMapTable: number_of_entries = 2
        frame_type = 0 /* same */
        frame_type = 43 /* same */

發(fā)現(xiàn)這次執(zhí)行后,從上到下整個(gè)方法都沒有monitorenter這個(gè)作為入口的關(guān)鍵字。雖然沒有找到但是我們可以在方法最上面找到這樣一行標(biāo)記:flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED。仔細(xì)觀察這行標(biāo)記,其實(shí)就是我們寫在方法前面的修飾詞:public、 static和synchronized。其實(shí)ACC_SYNCHRONIZED就是互斥開始標(biāo)記,一旦發(fā)現(xiàn)這個(gè)標(biāo)記就表示這個(gè)方法是一個(gè)同步方法,或者叫互斥方法。當(dāng)一個(gè)線程執(zhí)行含有ACC_SYNCHRONIZED標(biāo)記的方法的時(shí)候,別的線程就無(wú)法調(diào)用這個(gè)方法。這個(gè)就是synchronized關(guān)鍵字對(duì)方法加鎖的原理。

總結(jié)

到此synchronized的基本原理和使用方法就告一段落了。本篇通過實(shí)例講解了synchronized的場(chǎng)景和synchronized的使用方法,通過反編譯class字節(jié)碼文件以后的輸出,分析出synchronized方法是用的ACC_SYNCHRONIZED信號(hào)作為互斥標(biāo)記,而synchronized塊則是用的monitorenter和monitorexit作為互斥標(biāo)記,兩種不同的機(jī)制去實(shí)現(xiàn)同步。但是某一塊代碼一旦被加上synchronized關(guān)鍵字以后,相當(dāng)于對(duì)其他線程鎖住了,因此synchronized算是一個(gè)相當(dāng)重量級(jí)的鎖。因此使用synchronized需要注意一些問題:

  1. 與moniter關(guān)聯(lián)的對(duì)象不能為空,也就是說synchronized參數(shù)不能為null。
  2. synchronized作用域太大,導(dǎo)致程序里有大量不必要的單線程執(zhí)行過程,而不是多線程執(zhí)行。
  3. 不同的monitor企圖鎖相同的方法,結(jié)果多個(gè)鎖的交叉導(dǎo)致出現(xiàn):A線程等B線程釋放資源,B線程等A線程釋放資源的死鎖問題

正是由于有這些問題,為了提高synchronized可用性,Java官方針對(duì)synchronized關(guān)鍵字也進(jìn)行了優(yōu)化

附:如何找到并使用Java反編譯文件

首先進(jìn)入項(xiàng)目路徑的/out路徑,找到.class文件:

在這里插入圖片描述

然后呼叫出控制臺(tái),進(jìn)入當(dāng)前目錄:

在這里插入圖片描述

輸入命令javap –v [字節(jié)碼名稱]打印額外信息。

在這里插入圖片描述

javap –v 命令說明:

在這里插入圖片描述

到此這篇關(guān)于Java線程中synchronized的用法與原理解析的文章就介紹到這了,更多相關(guān)synchronized用法與原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java快速實(shí)現(xiàn)PDF轉(zhuǎn)圖片功能實(shí)例代碼

    Java快速實(shí)現(xiàn)PDF轉(zhuǎn)圖片功能實(shí)例代碼

    PDFBox是一個(gè)開源Java類庫(kù),用于讀取和創(chuàng)建PDF文檔,它支持文本提取、表單處理、文檔加密解密、合并分割、內(nèi)容覆蓋追加、文檔打印和轉(zhuǎn)換等功能,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • 在webservice里調(diào)用耗時(shí)方法出錯(cuò)的解決方案

    在webservice里調(diào)用耗時(shí)方法出錯(cuò)的解決方案

    這篇文章主要介紹了在webservice里調(diào)用耗時(shí)方法出錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java連接Mongodb實(shí)現(xiàn)增刪改查

    java連接Mongodb實(shí)現(xiàn)增刪改查

    這篇文章主要為大家詳細(xì)介紹了java連接Mongodb實(shí)現(xiàn)增刪改查,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • SpringBoot整合Scala構(gòu)建Web服務(wù)的方法

    SpringBoot整合Scala構(gòu)建Web服務(wù)的方法

    這篇文章主要介紹了SpringBoot整合Scala構(gòu)建Web服務(wù)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java架構(gòu)設(shè)計(jì)之六步拆解 DDD

    Java架構(gòu)設(shè)計(jì)之六步拆解 DDD

    DDD(Domain-Driven Design 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))是由Eric Evans最先提出,目的是對(duì)軟件所涉及到的領(lǐng)域進(jìn)行建模,以應(yīng)對(duì)系統(tǒng)規(guī)模過大時(shí)引起的軟件復(fù)雜性的問題
    2022-02-02
  • java中@JsonFormat和@JSONField的使用方法詳解

    java中@JsonFormat和@JSONField的使用方法詳解

    這篇文章主要介紹了java中@JsonFormat和@JSONField使用的相關(guān)資料,@JsonFormat和@JSONField都是用于處理日期格式化的注解,但分別屬于不同的庫(kù)和框架,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • SpringBoot同時(shí)集成Mybatis和Mybatis-plus框架

    SpringBoot同時(shí)集成Mybatis和Mybatis-plus框架

    在實(shí)際開發(fā)中,項(xiàng)目里面一般都是Mybatis和Mybatis-Plus公用,但是公用有版本不兼容的問題,本文主要介紹了Spring Boot項(xiàng)目中同時(shí)集成Mybatis和Mybatis-plus,具有一檔的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • Java HttpClient-Restful工具各種請(qǐng)求高度封裝提煉及總結(jié)

    Java HttpClient-Restful工具各種請(qǐng)求高度封裝提煉及總結(jié)

    這篇文章主要介紹了Java HttpClient-Restful工具各種請(qǐng)求高度封裝提煉及總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Spring Boot啟動(dòng)流程斷點(diǎn)過程解析

    Spring Boot啟動(dòng)流程斷點(diǎn)過程解析

    這篇文章主要介紹了Spring Boot啟動(dòng)流程斷點(diǎn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 如何動(dòng)態(tài)替換Spring容器中的Bean

    如何動(dòng)態(tài)替換Spring容器中的Bean

    這篇文章主要介紹了如何動(dòng)態(tài)替換Spring容器中的Bean,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08

最新評(píng)論

开平市| 鄂伦春自治旗| 民勤县| 浪卡子县| 清徐县| 嘉定区| 庄河市| 惠来县| 南京市| 凭祥市| 泗水县| 开鲁县| 曲沃县| 麻城市| 天祝| 临高县| 马龙县| 横峰县| 江川县| 泽普县| 江华| 克东县| 惠安县| 玉溪市| 徐闻县| 安义县| 南平市| 房山区| 共和县| 克拉玛依市| 辽源市| 安平县| 苗栗市| 开江县| 隆林| 兴义市| 金阳县| 塔城市| 米泉市| 全州县| 武鸣县|