在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

JAVA最好的加鎖方法是什么

汽車玩家 ? 來源:oschina ? 作者:oschina ? 2020-05-03 17:44 ? 次閱讀

關于synchronized

眾所周知,JAVA中最簡單的加鎖方法是用關鍵字synchronized,我們可以使用這個關鍵字將一個方法變成線程安全的,也可以將一個代碼塊變成線程安全的,這樣子我們不需要再擔心多線程同時執行到這段代碼會引發的并發問題。同時配合方法wait,notify和notifyall可以很好的實現多線程之間的協作,比如某個線程因為需要等待一些資源,于是調用wait方法將自己設置為waiting狀態,其他線程釋放或生產這個線程需要的資源的時候需要通知這個線程(notify)將其喚醒,或者通知所有等待當前資源的線程(notifyall)。

然而當功能完成之后我們似乎并不滿足于此,于是我們開始考慮這么做的代價是什么,是否可以做的更好。

先說說這么做(使用synchronized)的代價是什么,當多個線程請求臨界資源的時候只能有一個線程得到滿足,那么其他的線程會做什么呢,他們會被阻塞,直到被通知(notify/notifyall)又有資源的時候才被喚醒進行再一次的鎖爭用,而后往復的是又只有一個線程能被得到滿足,其他的線程繼續進入阻塞狀態,而這個時候可能會有不斷的增加爭用線程。性能損耗的關鍵點在于線程的阻塞操作是由操作系統來完成的,在Linux系統下是由pthread_mutex_lock函數來完成。線程被阻塞之后便進入了內核調度態,這個過程發生了操作系統將保存用戶態的上下文進入內核態,這也就是常說的上下文切換,上下文切換代價大,在于操作系統需要將當前線程執行上下文內容(包括堆棧、寄存器等存儲的內容)的保存以便之后線程切換回來時候再進行現場恢復。

上面可以看出使用synchronized的代價是什么了吧,當競爭激烈的時候會引起頻繁的操作系統上下文切換,從而影響系統的性能。下面再來講講自旋鎖。

自旋鎖的原理

自旋鎖是對線程阻塞的一種優化,他的原理簡單的說就是當線程爭用鎖失敗的時候不立即進入阻塞狀態,而是再等一會,因為對于執行時間短的代碼這一會可能就會釋放鎖,而線程就不需要進行一次阻塞與喚醒。等待操作就是讓線程多執行幾個空指令,至于等待多久這跟具體的處理器實現有關,也有可能處理器根本不支持自旋鎖,具體實現的時候我們可以設置一個臨界值,當超過了這個臨界值之后我們就不自旋了,就乖乖進入阻塞狀態吧。這種優化對于執行時間短的代碼是很有效的。synchronized使用自旋鎖的時機是線程進入等待隊列即阻塞的前一步。

關于偏向鎖

偏向鎖是java6提供的一種功能,主要是對無競爭條件下的對加鎖代碼執行的優化,得到優化的地方是省去了對等待隊列的更新操作。在競爭條件下,獲取鎖失敗的線程會被放入等待隊列,這個隊列的更新操作是通過CAS指令來完成的。對于那么一段本部應該被加鎖的代碼被加了鎖,我們認為每次執行這段被加了鎖的代碼的時候更新等待隊列的操作并不是必要的,而CAS操作會延遲本地代碼的執行,因此偏向鎖是用于優化這個問題的。

關于Lock

Lock是JAVA5增加的內容,在JCU(java.util.concurrent.locks)包下面,作者是并發大師Doug Lea。JCU包提供了很多封裝的鎖,包括常用的ReentrantLock和ReadWriteLock。這些所其實都是依賴java.util.concurrent.AbstractQueuedSynchronizer這個類來實現的,這個類有個簡寫的名字叫AQS,對這就是著名的AQS。

關于Lock,先說說線程獲取Lock鎖的時候會引起哪些事件呢。首先AQS是依賴一個被volatile修飾的int變量來標識當前鎖的狀態的,為0的時候代表當前鎖不被任何線程擁有,當線程拿到這個鎖的時候會通過CAS操作修改state的狀態,那么對于爭用失敗的線程AQS會怎么辦呢,AQS內部維護了一個等待隊列,這個隊列是純JAVA實現的,其實現也是非常巧妙的,多線程在通過CAS來獲取自己在隊列中的位置,同時隊列中的線程狀態也是阻塞狀態,遇到阻塞就頭疼了,上面已經介紹過阻塞會帶來的性能問題。在源碼中我們可以看到的是AQS通過LockSupport(LockSupport底層依賴Unsafe)將線程阻塞,關于LockSupport我有一篇文章介紹的,其功能是用來代替wait和notity/notifyall的,更好的地方是LockSupport對park方法和unpark方法的調用沒有先后的限制,而notify/notifyall必須在wait調用之后調用。盡管如此,這一切并沒有阻止線程進入阻塞狀態,我有點失望。

無鎖時代

講到無鎖,必然是Disruptor并發框架,Disruptor底層依賴一個RingBuffer來進行線程之間的數據交換,無鎖在于在并發條件下,多線程對RingBuffer的讀和寫不會涉及到鎖,然而因為RingBuffer滿或者RingBuffer中沒有可消費內容引發的線程等待,那就要另當別論了。簡單幾句介紹下無鎖原理,RingBuffer維護者可讀和可寫的指針,也叫游標,它指向生產者或消費者需要寫或讀的位置,而對于指針的更新是由CAS來完成的,這個過程中我們不需要加鎖/解鎖的過程。

后記:

JAVA鎖方面的知識主要是要搞清楚不同的鎖的優點與缺點,深入到操作系統層的實現機制與不同場景中對應用的性能影響。本文簡單的擼了一下JAVA鎖從synchronized到無鎖的發展以及一些鎖的簡單原理,主要是拋磚引玉吧,因為介紹的比較簡單,對于文中提到的知識不知道的同學可以深入了解,我相信你會很有收獲。有些實現的原理介紹可能就一句話,但是實際實現起來是蠻復雜的,需要考慮到的東西是我們沒有寫過所不能考慮到的。到這里,如果你的項目中用到了多線程并發,你是否會考慮使用無鎖模型來優化你項目中多線程之間的通信呢。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5372

    瀏覽量

    121288
  • JAVA
    +關注

    關注

    19

    文章

    2976

    瀏覽量

    105217
收藏 人收藏

    評論

    相關推薦

    Java 23功能介紹

    Java 23 包含全新和更新的 Java 語言功能、核心 API 以及 JVM,同時適合新的 Java 開發者和高級開發者。從?IntelliJ IDEA 2024.2?開始已支持 Java
    的頭像 發表于 12-04 10:02 ?380次閱讀
    <b class='flag-5'>Java</b> 23功能介紹

    Java集合API的改進介紹

    解答這些問題。 我們將逐步學習 Java 集合類的優化過程,并按版本逐一對比分析。主要討論的焦點將包括 JDK 1.0、1.2、1.4、1.5、1.6、1.8、9、10、11 和 21 版本的 Java 集合功能 Java 集合
    的頭像 發表于 11-22 11:12 ?270次閱讀
    <b class='flag-5'>Java</b>集合API的改進介紹

    對比Python與Java編程語言

    Python與Java都是目前非常流行的編程語言,它們各有其獨特的優勢和適用場景。以下是對這兩種編程語言的對比: 一、語法和易用性 Python 語法簡潔,代碼更易讀,非常適合初學者。 動態類型系統
    的頭像 發表于 11-15 09:31 ?463次閱讀

    基于Java的工具Power Stage Designer

    電子發燒友網站提供《基于Java的工具Power Stage Designer.pdf》資料免費下載
    發表于 11-14 16:01 ?2次下載
    基于<b class='flag-5'>Java</b>的工具Power Stage Designer

    Java中時間戳的使用

    Java中時間戳的使用
    的頭像 發表于 11-06 16:04 ?273次閱讀
    <b class='flag-5'>Java</b>中時間戳的使用

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領域中的重要成員,它們各自具有獨特的優勢和特點,適用于不同的應用場景。以下將從語法特性、內存管理、跨平臺性、性能、應用領域等多個方面對C語言和Java語言進行詳細對比。
    的頭像 發表于 10-29 17:31 ?455次閱讀

    怎么在JAVA中確定線性池大小

    JAVA中確定線性池大小,分別介紹CPU密集型任務和I/O密集型任務及其處理方法。
    的頭像 發表于 10-24 14:02 ?237次閱讀

    ?介紹一款Java開發的開源MES系統

    ?介紹一款Java開發的開源MES系統,萬界星空科技開源的MES系統。該系統基于Java開發,具有廣泛的適用性和高度的可定制性,能夠滿足不同行業、不同規模企業的智能制造需求。
    的頭像 發表于 09-05 17:39 ?775次閱讀
    ?介紹一款<b class='flag-5'>Java</b>開發的開源MES系統

    java反編譯能拿到源碼嗎

    Java反編譯是一種將編譯后的Java字節碼(.class文件)轉換回Java源代碼的過程。雖然反編譯可以幫助理解代碼的邏輯和結構,但它并不總是能完美地還原原始源代碼。反編譯工具通常會產生與原始代碼
    的頭像 發表于 09-02 11:03 ?1207次閱讀

    java子類可以繼承父類的什么

    Java是一種面向對象的編程語言,它支持繼承的概念。繼承是面向對象編程的三大特性之一,它允許一個類(稱為子類或派生類)繼承另一個類(稱為父類或基類)的屬性和方法。在Java中,子類可以繼承父類
    的頭像 發表于 08-20 11:02 ?1433次閱讀

    ESP32會不會有多線程問題,需要加鎖嗎?

    ESP32會不會有多線程問題,需要加鎖
    發表于 07-19 08:05

    華納云:java web和java有什么區別java web和java有什么區別

    Java Web和Java是兩個不同的概念,它們在功能、用途和實現方式上存在一些區別,下面將詳細介紹它們之間的區別。 1. 功能和用途: – Java是一種編程語言,它提供了一種用于開發各種應用程序
    的頭像 發表于 07-16 13:35 ?924次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別

    Oracle確認Java/JDK 11官方支持延長至2032年1月?

    此外,Solaris操作系統上的Java SE 8和Java SE 11的官方支持也同步延期至2030年12月及2032年1月,進一步延長了該平臺上的Java服務周期。
    的頭像 發表于 05-16 15:57 ?1471次閱讀

    已經安裝了Java,且依然提示安裝Java是為什么?

    我已經在機器上安裝了最新版的 Java 10,打開 Cube 卻得到要求安裝 Java 1.7.0_45 的提示。何解?Eclipse CDT 依賴 Java,不可卸載重裝。
    發表于 04-26 06:23

    java實現多線程的幾種方式

    Java實現多線程的幾種方式 多線程是指程序中包含了兩個或以上的線程,每個線程都可以并行執行不同的任務或操作。Java中的多線程可以提高程序的效率和性能,使得程序可以同時處理多個任務。 Java提供
    的頭像 發表于 03-14 16:55 ?792次閱讀
    主站蜘蛛池模板: 黄视频福利 | 亚洲人成77777在线观看网 | 五月天久久婷婷 | 色视频在线免费观看 | 免费观看成年欧美1314www色 | 福利色播 | 深夜影院一级毛片 | 综合色久| 国产精品综合色区在线观看 | 国产欧美久久久精品影院 | 天堂网资源 | 天堂在线视频 | 亚洲88av| 国产在线精品一区二区夜色 | 国产精品性| 国产人成精品香港三级古代 | 欧美操bb | 亚洲欧美日本视频 | 丁香婷婷激情五月 | 永久免费视频网站在线观看 | 波多野结衣中文字幕教师 | 黄色片网站大全 | www.妖精视频| 视频在线观看一区二区 | 性欧美大战久久久久久久 | 四虎影院最新 | 午夜高清免费在线观看 | 亚洲色图 在线视频 | 久久国产乱子伦精品免费看 | 午夜国产精品久久影院 | 日韩高清在线日韩大片观看网址 | 免费看va| 成人国产亚洲欧美成人综合网 | 色多多高清在线观看视频www | 天天做天天爱夜夜大爽完整 | 爱操综合 | 免费我看视频在线观看 | 免费观看成年欧美1314www色 | 思思久99久女女精品 | 亚洲手机看片 | 男女交性动态免费视频 |