Java 中的鎖原理、鎖優化、CAS、AQS 詳解!


                <section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px;" data-mpa-powered-by="yiban.io"><p style="text-align: right;"><span style="font-family: 微軟雅黑, &quot;Microsoft YaHei&quot;caret-color: rgb(255, 0, 0);font-size: 10px;color: rgb(178, 178, 178);">來源:jianshu.com/p/e674ee68fd3f</span></p><h1 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">1、為什么要用鎖?</span></h1><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">鎖-是為了解決並發操作引起的臟讀、數據不一致的問題。</span></p><p><br></p><h1 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2、鎖實現的基本原理</span></h1><p><br></p><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.1、volatile</span></h2><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">Java編程語言允許線程訪問共享變量, 為了確保共享變量能被准確和一致地更新,線程應該確保通過排他鎖單獨獲得這個變量。Java語言提供了volatile,在某些情況下比鎖要更加方便。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">volatile在多處理器開發中保證了共享變量的“ 可見性”。可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="262" data-ratio="0.4588235294117647" data-type="png" data-w="765" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn0KE1Bu0k2NSRU6nCd4hA6CIibxHz1IkgiaQWc9Hff2QP3M2nt1OjOzjg/640?wx_fmt=png" _width="677px" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133233180-190053147.png" style="width: 677px !important; height: auto !important; visibility: visible !important;" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">結論:如果volatile變量修飾符使用恰當的話,它比synchronized的使用和執行成本更低,因為它不會引起線程上下文的切換和調度。</span></p><p><br></p><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2、synchronized</span></h2><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">synchronized通過鎖機制實現同步。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">先來看下利用synchronized實現同步的基礎:Java中的每一個對象都可以作為鎖。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">具體表現為以下3種形式。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">對於普通同步方法,鎖是當前實例對象。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">對於靜態同步方法,鎖是當前類的Class對象。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">對於同步方法塊,鎖是Synchonized括號里配置的對象。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">當一個線程試圖訪問同步代碼塊時,它首先必須得到鎖,退出或拋出異常時必須釋放鎖。</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2.1 synchronized實現原理</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">synchronized是基於Monitor來實現同步的。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">Monitor從兩個方面來支持線程之間的同步:</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">互斥執行</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">協作</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">1、Java 使用</span><span style="font-size: 15px;caret-color: red;font-family: 微軟雅黑, 'Microsoft YaHei';">對象鎖 ( 使用 synchronized 獲得對象鎖 ) 保證工作在共享的數據集上的線程互斥執行。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2、使用 notify/notifyAll/wait 方法來協同不同線程之間的工作。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3、Class和Object都關聯了一個Monitor。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="499" data-cropsely1="0" data-cropsely2="318" data-ratio="0.638" data-type="png" data-w="500" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8A7zT9dIqTJ6wsa8ekVdd1NdIbqhoX2NCictftP489Z7ZToMicxPyVtA/640?wx_fmt=png" data-backw="500" data-backh="319" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8A7zT9dIqTJ6wsa8ekVdd1NdIbqhoX2NCictftP489Z7ZToMicxPyVtA/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133253812-2128863132.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">Monitor 的工作機理</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">線程進入同步方法中。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">為了繼續執行臨界區代碼,線程必須獲取 Monitor 鎖。如果獲取鎖成功,將成為該監視者對象的擁有者。任一時刻內,監視者對象只屬於一個活動線程(The Owner)</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">擁有監視者對象的線程可以調用 wait() 進入等待集合(Wait Set),同時釋放監視鎖,進入等待狀態。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">其他線程調用 notify() / notifyAll() 接口喚醒等待集合中的線程,這些等待的線程需要重新獲取監視鎖后才能執行 wait() 之后的代碼。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">同步方法執行完畢了,線程退出臨界區,並釋放監視鎖。</span></p><p><br></p><p>參考文檔:<span style="color: #A5A5A5;font-size: 15px;">https://www.ibm.com/developerworks/cn/java/j-lo-synchronized</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2.2 synchronized具體實現</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">1、同步代碼塊采用monitorenter、monitorexit指令顯式的實現。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2、同步方法則使用ACC_SYNCHRONIZED標記符隱式的實現。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">通過實例來看看具體實現:</span></p><p><br></p><pre style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;letter-spacing: 0.544px;color: rgb(52, 73, 94);background-color: rgb(255, 255, 255);font-family: Consolas, Menlo, Courier, monospace;box-sizing: border-box !important;word-wrap: break-word !important;"><code class="hljs java" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);padding: 0.5em;font-size: 11px;max-width: 100%;display: block;overflow-x: auto;line-height: 15px;word-spacing: -3px;letter-spacing: 0px;background: rgb(29, 31, 33);color: rgb(197, 200, 198);font-family: Consolas, Inconsolata, Courier, monospace;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: normal !important;word-break: normal !important;overflow-y: auto !important;"><span class="" style="max-width: 100%;color: rgb(178, 148, 187);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="hljs-keyword"><span class="hljs-keyword">public</span></span></span>&nbsp;<span class="" style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword">class</span></span></span></span></span><span class="hljs-class"><span class="hljs-class">&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(129, 162, 190);word-break: inherit !important;"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">SynchronizedTest</span></span></span></span></span><span class="hljs-class"><span class="hljs-class">&nbsp;</span></span></span>{<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span><span class="hljs-function"><span class="hljs-function">&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">synchronized</span></span></span></span></span><span class="hljs-function"><span class="hljs-function">&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span><span class="hljs-function"><span class="hljs-function">&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(129, 162, 190);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">method1</span></span></span></span></span><span class="" style="max-width: 100%;color: rgb(222, 147, 95);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">()</span></span></span></span></span></span>{<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="" style="max-width: 100%;color: rgb(181, 189, 104);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="hljs-string"><span class="hljs-string">"Hello&nbsp;World!"</span></span></span>);<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;}<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span><span class="hljs-function"><span class="hljs-function">&nbsp;&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(178, 148, 187);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span><span class="hljs-function"><span class="hljs-function">&nbsp;</span></span><span class="" style="max-width: 100%;color: rgb(129, 162, 190);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">method2</span></span></span></span></span><span class="" style="max-width: 100%;color: rgb(222, 147, 95);word-break: inherit !important;"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">()</span></span></span></span></span></span>{<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="max-width: 100%;color: rgb(178, 148, 187);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="hljs-keyword"><span class="hljs-keyword">synchronized</span></span></span>&nbsp;(<span class="" style="max-width: 100%;color: rgb(178, 148, 187);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span>){<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="" style="max-width: 100%;color: rgb(181, 189, 104);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span class="hljs-string"><span class="hljs-string">"Hello&nbsp;World!"</span></span></span>);<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;}<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: inherit !important;word-break: inherit !important;"></code></pre><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">javap編譯后的字節碼如下:</span></p><p><br></p><figure style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);max-width: 100%;letter-spacing: 0.544px;color: rgb(52, 73, 94);background-color: rgb(255, 255, 255);font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;box-sizing: border-box !important;word-wrap: break-word !important;"><img class="" data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="784" data-ratio="1.3741666666666668" data-type="png" data-w="1200" title="" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnGKbI0kcSdRiaTVEIeDIHzQia2LuIOHcIknEmCpdHTADKh0m7XEWmFRqg/640?wx_fmt=png" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin-right: auto; margin-left: auto; border-style: solid; border-width: 2px; border-color: rgb(238, 238, 238); border-radius: 6px; display: block; box-sizing: border-box !important; overflow-wrap: break-word !important; visibility: visible !important; width: 100% !important; height: auto !important;" data-backw="570.025" data-backh="783.025" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnGKbI0kcSdRiaTVEIeDIHzQia2LuIOHcIknEmCpdHTADKh0m7XEWmFRqg/640?wx_fmt=png" _width="100%" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133315873-1830567477.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">monitorenter</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">每一個對象都有一個monitor,一個monitor只能被一個線程擁有。當一個線程執行到monitorenter指令時會嘗試獲取相應對象的</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">monitor,獲取規則如下:</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如果monitor的進入數為0,則該線程可以進入monitor,並將monitor進入數設置為1,該線程即為monitor的擁有者。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如果當前線程已經擁有該monitor,只是重新進入,則進入monitor的進入數加1,所以synchronized關鍵字實現的鎖是可重入的鎖。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如果monitor已被其他線程擁有,則當前線程進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">monitorexit</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">只有擁有相應對象的monitor的線程才能執行monitorexit指令。每執行一次該指令monitor進入數減1,當進入數為0時當前線程釋放monitor,此時其他阻塞的線程將可以嘗試獲取該monitor。</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2.3 鎖存放的位置</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">鎖標記存放在Java對象頭的Mark Word中。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="99" data-ratio="0.175" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn0Y5RS19A7pTVD6ibG6vxIdkxARsDDoV71XRrlrLnRhwD2kV4bYgfnRQ/640?wx_fmt=png" data-backw="574" data-backh="101" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn0Y5RS19A7pTVD6ibG6vxIdkxARsDDoV71XRrlrLnRhwD2kV4bYgfnRQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133405678-40897258.png" crossorigin="anonymous" data-fail="0"><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">Java對象頭長度</span></figcaption></figure><figure><img data-backh="62" data-backw="574" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz/QCu849YTaIPksEhmXNlhegkc6ice6GYEnBA28fkQTqCR1Ju9yldmCcgNCPJ1NX0QaYFKINM78RMiats7rTwFX3Gg/640?wx_fmt=other" data-oversubscription-url="http://mmbiz.qpic.cn/mmbiz_jpg/SUicwdN39QsPJmMqSzaTSOHe08McwPRo00ibW8dXuicECprdI9fJvHkibnlto2h8EbAicAjATALJqy2GAlFYxeHl0UA/0?wx_fmt=jpeg" data-ratio="0.11" data-src="https://mmbiz.qpic.cn/mmbiz_jpg/SUicwdN39QsPJmMqSzaTSOHe08McwPRo00ibW8dXuicECprdI9fJvHkibnlto2h8EbAicAjATALJqy2GAlFYxeHl0UA/640?wx_fmt=jpeg" data-type="jpeg" data-w="1200" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133432358-1895366965.png" crossorigin="anonymous" data-fail="0"><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">32位JVM Mark Word 結構</span></figcaption></figure><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="132" data-ratio="0.23166666666666666" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnVrmfqajSfia99uJFVViaq3iax3cC3a6HLOgu4IBI5MmOHEIbeYhbiaOfTw/640?wx_fmt=png" data-backw="574" data-backh="133" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnVrmfqajSfia99uJFVViaq3iax3cC3a6HLOgu4IBI5MmOHEIbeYhbiaOfTw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133453495-1950846084.png" crossorigin="anonymous" data-fail="0"><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">32位JVM Mark Word 狀態變化</span></figcaption></figure><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="96" data-ratio="0.16916666666666666" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEno7R9LPLGo3OSmiaLZI43120UwcUN6iaiaXwXpjBceZHC8wiaGoXSDpxgsQ/640?wx_fmt=png" data-backw="574" data-backh="97" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEno7R9LPLGo3OSmiaLZI43120UwcUN6iaiaXwXpjBceZHC8wiaGoXSDpxgsQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src=https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133510746-1611249084.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">64位JVM Mark Word 結構</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2.3 synchronized的鎖優化</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">JavaSE1.6為了減少獲得鎖和釋放鎖帶來的性能消耗,引入了“偏向鎖”和“輕量級鎖”。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">在JavaSE1.6中,鎖一共有4種狀態,級別從低到高依次是:無鎖狀態、偏向鎖狀態、輕量級鎖狀態和重量級鎖狀態,這幾個狀態會隨着競爭情況逐漸升級。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">鎖可以升級但不能降級,意味着偏向鎖升級成輕量級鎖后不能降級成偏向鎖。這種鎖升級卻不能降級的策略,目的是為了提高獲得鎖和釋放鎖的效率。</span></p><p><br></p><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">偏向鎖:</span></h4><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">無鎖競爭的情況下為了減少鎖競爭的資源開銷,引入偏向鎖。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="556" data-ratio="0.975" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEneNic6BzhLGIN2p4uPHwrP9cBHbg8AaSgyqJCDBgJxMMeUlMAkcfOlvw/640?wx_fmt=png" data-backw="574" data-backh="559" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEneNic6BzhLGIN2p4uPHwrP9cBHbg8AaSgyqJCDBgJxMMeUlMAkcfOlvw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133529252-1066047276.png" crossorigin="anonymous" data-fail="0"></figure><h4 style="font-weight: bold;line-height: 1.6;"></h4><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h4><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">輕量級鎖:</span></h4><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">輕量級鎖所適應的場景是線程交替執行同步塊的情況</span><span style="font-size: 15px;caret-color: red;font-family: 微軟雅黑, 'Microsoft YaHei';">。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="556" data-ratio="0.975" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEneNic6BzhLGIN2p4uPHwrP9cBHbg8AaSgyqJCDBgJxMMeUlMAkcfOlvw/640?wx_fmt=png" data-backw="574" data-backh="559" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEneNic6BzhLGIN2p4uPHwrP9cBHbg8AaSgyqJCDBgJxMMeUlMAkcfOlvw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133551972-160806677.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">鎖粗化(Lock Coarsening):也就是減少不必要的緊連在一起的unlock,lock操作,將多個連續的鎖擴展成一個范圍更大的鎖。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">鎖消除(Lock Elimination):鎖削除是指虛擬機即時編譯器在運行時,對一些代碼上要求同步,但是被檢測到不可能存在共享數據競爭的鎖進行削除。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">適應性自旋(Adaptive Spinning):自適應意味着自旋的時間不再固定了,而是由前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態來決定。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如果在同一個鎖對象上,自旋等待剛剛成功獲得過鎖,並且持有鎖的線程正在運行中,那么虛擬機就會認為這次自旋也很有可能再次成功,進而它將允許自旋等待持續相對更長的時間,比如100個循環。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">另一方面,如果對於某個鎖,自旋很少成功獲得過,那在以后要獲取這個鎖時將可能省略掉自旋過程,以避免浪費處理器資源。</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.2.4 鎖的優缺點對比</span></h3><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="146" data-ratio="0.25583333333333336" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnUaFbGdC0zfEbiaicq6bWK4FZJ6RqVJOCtjica8exVZB4KZLmd1s7BcnAQ/640?wx_fmt=png" data-backw="574" data-backh="146" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnUaFbGdC0zfEbiaicq6bWK4FZJ6RqVJOCtjica8exVZB4KZLmd1s7BcnAQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133615526-2001355017.png" crossorigin="anonymous" data-fail="0"></figure><h2 style="font-weight: bold;line-height: 1.6;"></h2><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h2><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2.3、CAS</span></h2><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">CAS,在Java並發應用中通常指CompareAndSwap或CompareAndSet,即比較並交換。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">1、CAS是一個原子操作,它比較一個內存位置的值並且只有相等時修改這個內存位置的值為新的值,保證了新的值總是基於最新的信息計算的,如果有其他線程在這期間修改了這個值則CAS失敗。CAS返回是否成功或者內存位置原來的值用於判斷是否CAS成功。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">2、JVM中的CAS操作是利用了處理器提供的CMPXCHG指令實現的。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">優點:</span></p><p><br></p><ul class="list-paddingleft-2" style="list-style-type: none;"><li><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">競爭不大的時候系統開銷小。</span></p></li><li><p><br></p></li></ul><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">缺點:</span></p><p><br></p><ul class="list-paddingleft-2" style="list-style-type: none;"><li><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">循環時間長開銷大。</span></p></li><li><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">ABA問題。</span></p></li><li><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">只能保證一個共享變量的原子操作。</span></p></li><li><p><br></p></li></ul><h1 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3、Java中的鎖實現</span></h1><p><br></p><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3.1、隊列同步器(AQS)</span></h2><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">隊列同步器AbstractQueuedSynchronizer(以下簡稱同步器),是用來構建鎖或者其他同步組件的基礎框架。</span></p><p><br></p><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3.1.1、它使用了一個int成員變量表示同步狀態。</span></h3><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="152" data-ratio="0.26666666666666666" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8XHoomr2cquAaEUFe2z5icicIRbJibPyYN36JLoYQTsW4SHsdo7DLPxEw/640?wx_fmt=png" data-backw="574" data-backh="154" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8XHoomr2cquAaEUFe2z5icicIRbJibPyYN36JLoYQTsW4SHsdo7DLPxEw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133632853-1001996493.png" crossorigin="anonymous" data-fail="0"></figure><h3 style="font-weight: bold;line-height: 1.6;"></h3><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h3><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3.1.2、通過內置的FIFO雙向隊列來完成獲取鎖線程的排隊工作。</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">同步器包含兩個節點類型的應用,一個指向頭節點,一個指向尾節點,未獲取到鎖的線程會創建節點線程安全(compareAndSetTail)的加入隊列尾部。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">同步隊列遵循FIFO,首節點是獲取同步狀態成功的節點。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></p><ul class="list-paddingleft-2" style="list-style-type: none;"><li><figure><img data-cropselx1="0" data-cropselx2="533" data-cropsely1="0" data-cropsely2="173" data-ratio="0.325" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnXAnZMvGKdXibQGBtM3S8EboqtiaqZLjicZgrGdYvBCdKGib6SVjjV5m3Gw/640?wx_fmt=png" data-backw="539" data-backh="175" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnXAnZMvGKdXibQGBtM3S8EboqtiaqZLjicZgrGdYvBCdKGib6SVjjV5m3Gw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133648791-1050811559.png" crossorigin="anonymous" data-fail="0"></figure></li></ul><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">未獲取到鎖的線程將創建一個節點,設置到尾節點。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如下圖所示:</span></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="208" data-ratio="0.365" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnFiahtwJRMYh0Hp4Y8Lia79AMcUmGbJInKnIicIMuiaCpkjAFLgsJ1YpI8g/640?wx_fmt=png" data-backw="574" data-backh="210" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnFiahtwJRMYh0Hp4Y8Lia79AMcUmGbJInKnIicIMuiaCpkjAFLgsJ1YpI8g/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133719973-431134712.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">首節點的線程在釋放鎖時,將會喚醒后繼節點。而后繼節點將會在獲取鎖成功時將自己設置為首節點。</span></p><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">如下圖所示:</span></p><figure><img data-cropselx1="2" data-cropselx2="531" data-cropsely1="0" data-cropsely2="193" data-ratio="0.27666666666666667" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnUN3do5UjazdvBic02SQsmkGub6eMBMR8ssYcBaUfXjJ0tV1ribPj68LQ/640?wx_fmt=png" data-backw="574" data-backh="158" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnUN3do5UjazdvBic02SQsmkGub6eMBMR8ssYcBaUfXjJ0tV1ribPj68LQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133736561-138963095.png" crossorigin="anonymous" data-fail="0"></figure><h3 style="font-weight: bold;line-height: 1.6;"></h3><h3 style="font-weight: bold;line-height: 1.6;"><br></h3><h3 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">3.1.3、獨占式/共享式鎖獲取</span></h3><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">獨占式:有且只有一個線程能獲取到鎖,如:ReentrantLock。</span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">共享式:可以多個線程同時獲取到鎖,如:CountDownLatch</span></p><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h4><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">獨占式</span></h4><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">每個節點自旋觀察自己的前一節點是不是Header節點,如果是,就去嘗試獲取鎖。</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="533" data-cropsely1="0" data-cropsely2="135" data-ratio="0.255" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnMNHticMMzBsDdSDGbp2s4N7yckcQ4x6Qq2rTJRQlh1q6UL9vncZQj6w/640?wx_fmt=png" data-backw="574" data-backh="146" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnMNHticMMzBsDdSDGbp2s4N7yckcQ4x6Qq2rTJRQlh1q6UL9vncZQj6w/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133754059-1054383585.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">獨占式鎖獲取流程:</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="564" data-ratio="0.9883333333333333" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnETznz47tvRbtec3AoduyNcxASp8DMzerR794icPNkjPSYepeZn2jRkw/640?wx_fmt=png" data-backw="574" data-backh="568" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnETznz47tvRbtec3AoduyNcxASp8DMzerR794icPNkjPSYepeZn2jRkw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133809834-20395484.png" crossorigin="anonymous" data-fail="0"></figure><h4 style="font-weight: bold;line-height: 1.6;"></h4><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h4><h4 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">共享式:</span></h4><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">共享式與獨占式的區別:</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="533" data-cropsely1="0" data-cropsely2="300" data-ratio="0.565" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn1qeTXibFkuxicOcHibkJRowMQTRa8JKX9YQDNvQcbiaDB0hGYq7AFhT0YQ/640?wx_fmt=png" data-backw="574" data-backh="324" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn1qeTXibFkuxicOcHibkJRowMQTRa8JKX9YQDNvQcbiaDB0hGYq7AFhT0YQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133833324-2045100329.png" crossorigin="anonymous" data-fail="0"></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">共享鎖獲取流程:</span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="403" data-ratio="0.7061923583662714" data-type="png" data-w="759" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnNMyJGl6b1w1Obwqfl9kPwrgluJ8CTafxURicNXFGf9JLu7iaNHpZ3ruQ/640?wx_fmt=png" data-backw="574" data-backh="406" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnNMyJGl6b1w1Obwqfl9kPwrgluJ8CTafxURicNXFGf9JLu7iaNHpZ3ruQ/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133847909-32641824.png" crossorigin="anonymous" data-fail="0"></figure><h1 style="font-weight: bold;line-height: 1.6;"></h1><h1 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></h1><h1 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">4</span>、鎖的使用用例</h1><p><br></p><h2 style="font-weight: bold;line-height: 1.6;"><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">4.1、ConcurrentHashMap的實現原理及使用</span></h2><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></p><p><br></p><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="466" data-ratio="0.8166666666666667" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnzHK1Qt9ibEicX0HXspWBKz5TxPqia8SFusYBdwZJTA4N04n45ngRtqQgw/640?wx_fmt=png" data-backw="574" data-backh="469" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEnzHK1Qt9ibEicX0HXspWBKz5TxPqia8SFusYBdwZJTA4N04n45ngRtqQgw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133903649-1059587046.png" crossorigin="anonymous" data-fail="0"><figcaption><br></figcaption><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">ConcurrentHashMap類圖</span></figcaption><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';"><br></span></figcaption></figure><figure><img data-cropselx1="0" data-cropselx2="570" data-cropsely1="0" data-cropsely2="292" data-ratio="0.5108333333333334" data-type="png" data-w="1200" data-src="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8WYuoicLufp6B4Hu71YCdvtJRIKXfGI6T9bfAda4z7rRiauP5kR3ILXw/640?wx_fmt=png" data-backw="574" data-backh="293" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/QCu849YTaIPksEhmXNlhegkc6ice6GYEn8WYuoicLufp6B4Hu71YCdvtJRIKXfGI6T9bfAda4z7rRiauP5kR3ILXw/640?wx_fmt=png" style="width: 100% !important; height: auto !important; visibility: visible !important;" _width="100%" class="" src="https://img2018.cnblogs.com/blog/1112483/201911/1112483-20191112133919142-1191235800.png" crossorigin="anonymous" data-fail="0"><figcaption><br></figcaption><figcaption><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">ConcurrentHashMap數據結構</span></figcaption></figure><p><br></p><p><span style="font-size: 15px;font-family: 微軟雅黑, 'Microsoft YaHei';">結論:ConcurrentHashMap使用的鎖分段技術。首先將數據分成一段一段地存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。</span></p></section>
    原文地址:https://mp.weixin.qq.com/s/3BITJAlZUa2AoVFtcV7xsA        </div>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM