怎樣深入理解Java多線程與并發(fā)框中的synchronized關(guān)鍵字-創(chuàng)新互聯(lián)

怎樣深入理解Java多線程與并發(fā)框中的synchronized 關(guān)鍵字,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

站在用戶的角度思考問題,與客戶深入溝通,找到福貢網(wǎng)站設(shè)計與福貢網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋福貢地區(qū)。

一、Class文件與對象

對象頭 32位JVM的對象頭

二、synchronized 三種應(yīng)用方式

用于實例對象方法(對象是鎖) 用于靜態(tài)方法(類是鎖) 用于同步代碼塊(同步代碼塊是鎖)

三、synchronized 底層語義原理

鎖:就在對象頭中

Java 虛擬機中的同步(Synchronization)基于 進入enter 和 退出exit 監(jiān)視器(Monitor)對象 實現(xiàn), 無論是顯式同步(有明確的 monitorenter 和 monitorexit 指令,即同步代碼塊)還是隱式同步都是如此。在 Java 語言中,同步用的最多的地方可能是被 synchronized 修飾的同步方法。同步方法 并不是由 monitorenter 和 monitorexit 指令來實現(xiàn)同步的,而是由方法調(diào)用指令讀取運行時常量池中方法的 ACC_SYNCHRONIZED 標志來隱式實現(xiàn)的,關(guān)于這點,稍后詳細分析。下面先來了解一個概念Java對象頭,這對深入理解synchronized實現(xiàn)原理非常關(guān)鍵。

1. 對象加鎖: 使用 monitorenter 和 monitorexit 指令分別獲取控制權(quán)和釋放控制權(quán)。

2. 方法加鎖:

方法級的同步是隱式,即無需通過字節(jié)碼指令來控制的,它實現(xiàn)在方法調(diào)用和返回操作之中。JVM可以從方法常量池中的方法表結(jié)構(gòu)(method_info Structure) 中的 ACC_SYNCHRONIZED 訪問標志區(qū)分一個方法是否同步方法。當方法調(diào)用時,調(diào)用指令將會檢查方法的 ACC_SYNCHRONIZED 訪問標志是否被設(shè)置,如果設(shè)置了,執(zhí)行線程將先持有monitor(虛擬機規(guī)范中用的是監(jiān)視器一詞), 然后再執(zhí)行方法,最后再方法完成(無論是正常完成還是非正常完成)時釋放monitor。在方法執(zhí)行期間,執(zhí)行線程持有了monitor,其他任何線程都無法再獲得同一個monitor。如果一個同步方法執(zhí)行期間拋 出了異常,并且在方法內(nèi)部無法處理此異常,那這個同步方法所持有的monitor將在異常拋到同步方法之外時自動釋放。

四、JVM對synchronized的優(yōu)化

背景:Java 6之后,為了減少獲得鎖和釋放鎖所帶來的性能消耗,引入了 偏向鎖 和 輕量級鎖。 鎖的狀態(tài):無鎖狀態(tài)、偏向鎖、輕量級鎖、重量級鎖。 鎖從 偏向鎖 -> 輕量級鎖 -> 重量級鎖 的鎖升級是單向的、不可逆的,沒有 鎖降級 這一說。

1. 偏向鎖

因此為了減少同一線程獲取鎖(會涉及到一些CAS操作,耗時)的代價而引入偏向鎖。偏向鎖的核心思想是,如果一個線程獲得了鎖,那么鎖就進入偏向模式,此時Mark Word 的結(jié)構(gòu)也變?yōu)槠蜴i結(jié)構(gòu),當這個線程再次請求鎖時,無需再做任何同步操作,即獲取鎖的過程,這樣就省去了大量有關(guān)鎖申請的操作,從而也就提供程序的性能。

2. 輕量級鎖

輕量級鎖所適應(yīng)的場景是 線程交替執(zhí)行同步塊 的場合,如果存在 同一時刻訪問同一鎖 的場合,就會導(dǎo)致輕量級鎖膨脹為重量級鎖。

3. 自旋鎖

自旋鎖是樂觀的一種表現(xiàn),樂觀的認為很大概率是能夠獲得鎖的。(根據(jù)阿里巴巴Java開發(fā)規(guī)范:如果每次訪問沖突的概率小于 20%,推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重試次數(shù)不得小于3次。)

4. 重入鎖

從互斥鎖的設(shè)計上來說,當一個線程試圖操作一個由其他線程持有的對象鎖的臨界資源時,將會處于阻塞狀態(tài),但當一個線程再次請求自己持有對象鎖的臨界區(qū)的資源時,這種情況屬于 *重入鎖,請求將會成功,在java中synchronized是基于原子性的內(nèi)部鎖機制,是可重入的,因此在一個線程調(diào)用synchronized方法的同時在其方法體內(nèi)部調(diào)用該對象另一個synchronized方法,也就是說一個線程得到一個對象鎖后再次請求該對象鎖,是允許的,這就是synchronized的可重入性。

5. 鎖消除

消除鎖是虛擬機另外一種鎖的優(yōu)化,這種優(yōu)化更徹底,Java虛擬機在JIT編譯時(可以簡單理解為當某段代碼即將第一次被執(zhí)行時進行編譯,又稱即時編譯),通過對運行上下文的掃描,去除不可能存在共享資源競爭的鎖,通過這種方式消除沒有必要的鎖,可以節(jié)省毫無意義的請求鎖時間,如下StringBuffer的append是一個同步方法,但是在add方法中的StringBuffer屬于一個局部變量,并且不會被其他線程所使用,因此StringBuffer不可能存在共享資源競爭的情景,JVM會自動將其鎖消除。

五、synchronized關(guān)鍵點

中斷與synchronized: 事實上線程的中斷操作對于正在等待獲取的鎖對象的synchronized方法或者代碼塊并不起作用,也就是對于synchronized來說,如果一個線程在等待鎖,那么結(jié)果只有兩種,要么它獲得這把鎖繼續(xù)執(zhí)行,要么它就保存等待,即使調(diào)用中斷線程的方法,也不會生效。

看完上述內(nèi)容,你們掌握怎樣深入理解Java多線程與并發(fā)框中的synchronized 關(guān)鍵字的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站名稱:怎樣深入理解Java多線程與并發(fā)框中的synchronized關(guān)鍵字-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://bm7419.com/article36/gjdpg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)網(wǎng)站收錄、App設(shè)計、網(wǎng)頁設(shè)計公司、營銷型網(wǎng)站建設(shè)網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)