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

Java StringBuffer與StringBuilder有什么區(qū)別

 更新時間:2023年01月18日 10:20:41   作者:hudawei996  
當(dāng)對字符串進行修改的時候,需要使用 StringBuffer 和 StringBuilder類,和String類不同的是,StringBuffer和 StringBuilder類的對象能夠被多次的修改,并且不產(chǎn)生新的未使用對象,本篇我們來分析分析它們的區(qū)別

一問道StringBuffer與StringBuilder的區(qū)別,張口就來StringBuffer是線程安全的,因為它相關(guān)方法都加了synchronized 關(guān)鍵字,StringBuilder線程不安全。沒錯,確實如此,但是我們查看過源碼會發(fā)現(xiàn)StringBuffer是從jdk1.0就開始了,StringBuilder是從jdk1.5開始的。于是我就產(chǎn)生這樣一個疑問,既然已經(jīng)有了StringBuffer,為什么jdk5又出了一個StringBuilder呢,也就是單線程時候StringBuffer與StringBuilder有什么區(qū)別。

一、StringBuffer與StringBuilder的共同之處

1、都繼成了AbstractStringBuilder這個抽象類,實現(xiàn)了CharSequence接口

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

2、其append方法都是 super.append(str),調(diào)用了父類AbstractStringBuilder的append(String str)方法

  @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

3、初始容量都是16和擴容機制都是"舊容量*2+2"

4、底層都是用char[]字符數(shù)組實現(xiàn),且字符數(shù)組都是可變的,這點不同于String

二、StringBuffer與StringBuilder的不同之處

  • StringBuffer多線程安全的,StringBuilder多線程不安全
  • StringBuffer從JDK1.0就有了,StringBuilder是JDK5.0才出現(xiàn)
  • StringBuffer比StringBuilder多了一個toStringCache字段,用來在toString方法中進行緩存,每次append操作之前都先把toStringCache設(shè)置為null,若多次連續(xù)調(diào)用toString方法,可避免每次Arrays.copyOfRange(value, 0, count)操作,節(jié)省性能。
 @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

4、由于StringBuilder沒有考慮同步,在單線程情況下,StringBuilder的性能要優(yōu)于StringBuffer

三、單線程StringBuffer與StringBuilder區(qū)別

這個才是我們重點討論的,單線程下StringBuffer加了synchronized,雖然是單線程, 但是synchronized獲取鎖和釋放鎖也還是需要時間的, 而StringBuilder沒有,這個就是重點區(qū)別。因此重點要討論synchronized鎖的狀態(tài),從獲取鎖到釋放鎖的過程,因此需要討論一下鎖的升級和優(yōu)化。

鎖的4中狀態(tài):無鎖狀態(tài)、偏向鎖狀態(tài)、輕量級鎖狀態(tài)、重量級鎖狀態(tài)(級別從低到高)

(1)偏向鎖:

偏向鎖是指一段同步代碼一直被一個線程所訪問,那么該線程會自動獲取鎖。降低獲取鎖的代價。

為什么要引入偏向鎖?

因為經(jīng)過HotSpot的作者大量的研究發(fā)現(xiàn),大多數(shù)時候是不存在鎖競爭的,常常是一個線程多次獲得同一個鎖,因此如果每次都要競爭鎖會增大很多沒有必要付出的代價,為了降低獲取鎖的代價,才引入的偏向鎖。

偏向鎖的升級

當(dāng)線程1訪問代碼塊并獲取鎖對象時,會在java對象頭和棧幀中記錄偏向的鎖的threadID,因為偏向鎖不會主動釋放鎖,因此以后線程1再次獲取鎖的時候,需要比較當(dāng)前線程的threadID和Java對象頭中的threadID是否一致,如果一致(還是線程1獲取鎖對象),則無需使用CAS來加鎖、解鎖;如果不一致(其他線程,如線程2要競爭鎖對象,而偏向鎖不會主動釋放因此還是存儲的線程1的threadID),那么需要查看Java對象頭中記錄的線程1是否存活,如果沒有存活,那么鎖對象被重置為無鎖狀態(tài),其它線程(線程2)可以競爭將其設(shè)置為偏向鎖;如果存活,那么立刻查找該線程(線程1)的棧幀信息,如果還是需要繼續(xù)持有這個鎖對象,那么暫停當(dāng)前線程1,撤銷偏向鎖,升級為輕量級鎖,如果線程1 不再使用該鎖對象,那么將鎖對象狀態(tài)設(shè)為無鎖狀態(tài),重新偏向新的線程。

偏向鎖的取消:

偏向鎖是默認(rèn)開啟的,而且開始時間一般是比應(yīng)用程序啟動慢幾秒,如果不想有這個延遲,那么可以使用-XX:BiasedLockingStartUpDelay=0;

如果不想要偏向鎖,那么可以通過-XX:-UseBiasedLocking = false來設(shè)置;

(2)輕量級鎖

輕量級鎖是指當(dāng)鎖是偏向鎖的時候,被另一個線程所訪問,偏向鎖就會升級為輕量級鎖,其他線程會通過自旋的形式嘗試獲取鎖,不會阻塞,提高性能

為什么要引入輕量級鎖?

輕量級鎖考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時間也不長的情景。因為阻塞線程需要CPU從用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài),代價較大,如果剛剛阻塞不久這個鎖就被釋放了,那這個代價就有點得不償失了,因此這個時候就干脆不阻塞這個線程,讓它自旋這等待鎖釋放。

(3)重量級鎖

重量級鎖是指當(dāng)鎖為輕量級鎖的時候,另一個線程雖然是自旋,但自旋不會一直持續(xù)下去,當(dāng)自旋一定次數(shù)的時候,還沒有獲取到鎖,就會進入阻塞,該鎖膨脹為重量級鎖。重量級鎖會讓其他申請的線程進入阻塞,性能降低。

輕量級鎖什么時候升級為重量級鎖?

線程1獲取輕量級鎖時會先把鎖對象的對象頭MarkWord復(fù)制一份到線程1的棧幀中創(chuàng)建的用于存儲鎖記錄的空間(稱為DisplacedMarkWord),然后使用CAS把對象頭中的內(nèi)容替換為線程1存儲的鎖記錄(DisplacedMarkWord)的地址;

如果在線程1復(fù)制對象頭的同時(在線程1CAS之前),線程2也準(zhǔn)備獲取鎖,復(fù)制了對象頭到線程2的鎖記錄空間中,但是在線程2CAS的時候,發(fā)現(xiàn)線程1已經(jīng)把對象頭換了,線程2的CAS失敗,那么線程2就嘗試使用自旋鎖來等待線程1釋放鎖。

但是如果自旋的時間太長也不行,因為自旋是要消耗CPU的,因此自旋的次數(shù)是有限制的,比如10次或者100次,如果自旋次數(shù)到了線程1還沒有釋放鎖,或者線程1還在執(zhí)行,線程2還在自旋等待,這時又有一個線程3過來競爭這個鎖對象,那么這個時候輕量級鎖就會膨脹為重量級鎖。重量級鎖把除了擁有鎖的線程都阻塞,防止CPU空轉(zhuǎn)。

*注意:為了避免無用的自旋,輕量級鎖一旦膨脹為重量級鎖就不會再降級為輕量級鎖了;偏向鎖升級為輕量級鎖也不能再降級為偏向鎖。一句話就是鎖可以升級不可以降級,但是偏向鎖狀態(tài)可以被重置為無鎖狀態(tài)。

綜上可知,StringBuffer雖然是單線程,但它是有偏向鎖升級過程判斷的,會耗費時間,效率固然低于StringBuilder

四、StringBuffer與StringBuilder的應(yīng)用場景

1、StringBuffer多線程安全,但是加了synchronized,其效率低。故適用于多線程下,并發(fā)量不是很高的場景

2、StringBuilder沒有加任何鎖,其效率高,適用單線程場景,但同時也適用于高并發(fā)場景中,提高高并發(fā)場景下程序的響應(yīng)性能,至于線程安全問題可以通過其它手段解決,如ThreadLocal,CAS操作等。

3、所以對于高并發(fā)場景下,若有用到二者,還是建議優(yōu)先使用StringBuilder的

到此這篇關(guān)于Java StringBuffer與StringBuilder有什么區(qū)別的文章就介紹到這了,更多相關(guān)Java StringBuffer與StringBuilder內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot Controller Post接口單元測試示例

    SpringBoot Controller Post接口單元測試示例

    今天小編就為大家分享一篇關(guān)于SpringBoot Controller Post接口單元測試示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java 中的FileReader和FileWriter源碼分析_動力節(jié)點Java學(xué)院整理

    Java 中的FileReader和FileWriter源碼分析_動力節(jié)點Java學(xué)院整理

    本文給大家分享一段示例程序,通過示例代碼可以看出FileReader是基于InputStreamReader實現(xiàn)的,FileWriter是基于OutputStreamWriter實現(xiàn)的,具體程序代碼大家通過本文了解下吧
    2017-05-05
  • Java web Hibernate如何與數(shù)據(jù)庫鏈接

    Java web Hibernate如何與數(shù)據(jù)庫鏈接

    這篇文章主要介紹了Java web Hibernate如何與數(shù)據(jù)庫鏈接,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • Java中的字符串用法小結(jié)

    Java中的字符串用法小結(jié)

    這篇文章主要介紹了Java中的字符串用法,實例總結(jié)了java中關(guān)于字符串操作的各種常用的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • Java常用工具類匯總 附示例代碼

    Java常用工具類匯總 附示例代碼

    這篇文章主要介紹了Java常用工具類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著我來一起學(xué)習(xí)學(xué)習(xí)吧,希望能給你帶來幫助
    2021-06-06
  • Java中的自旋鎖與適應(yīng)性自旋鎖詳解

    Java中的自旋鎖與適應(yīng)性自旋鎖詳解

    這篇文章主要介紹了Java中的自旋鎖與適應(yīng)性自旋鎖詳解,在多處理器環(huán)境中某些資源的有限性,有時需要互斥訪問,這時候就需要引入鎖的概念,只有獲取了鎖的線程才能對資源進行訪問,多線程的核心是CPU的時間分片,所以同一時刻只能有一個線程獲取到鎖,需要的朋友可以參考下
    2023-10-10
  • Java實戰(zhàn)之OutOfMemoryError異常問題及解決方法

    Java實戰(zhàn)之OutOfMemoryError異常問題及解決方法

    這篇文章主要介紹了Java實戰(zhàn)之OutOfMemoryError異常,主要結(jié)合著深入理解Java虛擬機一書當(dāng)中整理了本篇內(nèi)容,感興趣的朋友一起看看吧
    2022-04-04
  • 解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?error?(type=Not?Found,?status=404)

    解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?erro

    這篇文章主要介紹了解決springboot+thymeleaf視圖映射報錯There?was?an?unexpected?error?(type=Not?Found,?status=404)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java實現(xiàn)微信App支付服務(wù)端

    java實現(xiàn)微信App支付服務(wù)端

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)微信App支付服務(wù)端,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • springboot遠(yuǎn)程debug調(diào)試全過程

    springboot遠(yuǎn)程debug調(diào)試全過程

    這篇文章主要介紹了springboot遠(yuǎn)程debug調(diào)試全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論

兰溪市| 揭阳市| 丰都县| 河源市| 秦皇岛市| 定南县| 潢川县| 江都市| 体育| 潼南县| 盱眙县| 横峰县| 隆德县| 霍山县| 改则县| 唐河县| 于田县| 福安市| 治县。| 朝阳区| 弥渡县| 沁水县| 固安县| 抚州市| 清远市| 平乡县| 卢湾区| 湘乡市| 阳春市| 元江| 临澧县| 海盐县| 安达市| 吴江市| 于都县| 康保县| 天等县| 吴桥县| 无为县| 水富县| 武陟县|