synchronized內建鎖詳解

2021-09-25 21:11:01 字數 1745 閱讀 8540

synchronized內建鎖詳解

多執行緒訪問同一共享可變資源的情況下,會出現執行緒不安全問題,經典案例購買火車票:

public class testthread2 

public void getticket()

system.out.println(thread.currentthread().getname()+"拿到了第"+ticketnums--+"張票");

try catch (exception e)}}}

跑出來的結果如下:

要解決上述問題:1)可以在getticket()方法前加synchronized關鍵字

public synchronized void getticket(){}

2)新增synchronized**塊:

public void getticket()

system.out.println(thread.currentthread().getname()+「拿到了第」+ticketnums–+「張票」);

try catch (exception e)}}

}【注:****第乙個方案中的鎖物件是當前類物件; 第二個方案中的鎖物件是「123」,因為字串是放在jvm方法區的常量池中的,所以不用定義全域性變數,否則一定要定義全域性變數,鎖才生效。

對於上述這種形式的鎖是重量級的,每次都要呼叫jvm的pthread命令與cpu進行互動,效能消耗很大,所以jdk1.6以後對synchronized進行了優化,讓鎖狀態從無鎖到偏向鎖,到輕量級鎖,重量級鎖逐漸的進行不可逆的膨脹公升級。

1)無鎖:當執行緒沒有觸發的時候,鎖的狀態是無鎖。hotspot虛擬機器的物件頭的mark word 結構如下:

2)偏向鎖:當只有乙個執行緒執行該**塊,那鎖狀態改為偏向鎖,這樣就使該執行緒再次請求鎖時,省去以前的同步操作,直接獲取鎖。這種鎖只要沒有其它執行緒的介入不會釋放,一旦有其他執行緒與其競爭,就會公升級成輕量級鎖。【當然如果抱鎖線程到達安全點時正好執行完,就不用公升級,而是偏向剛進入的執行緒】mark word結構如下:

3)輕量級鎖:執行緒產生競爭時,虛擬機器先嘗試自旋一段時間,看對方會不會把輕量級鎖釋放掉,如果釋放掉,輕量鎖指標指向新的執行緒,否則公升級到重量級鎖。【自旋可以簡單理解成空的for迴圈執行50或100次,就是為了等待所釋放;自適應自旋,就是根據上一次得到鎖時的迴圈次數,計算這次自旋次數】mark word結構如下:

4)重量級鎖:輕量級鎖公升級成重量級鎖後,掛起未得到鎖的執行緒,得到鎖的執行緒到達安全點時,釋放原來的輕量鎖【一般會失敗】,同時喚醒所有執行緒,重新爭搶時間片。mark word結構如下:

012 內建鎖和synchronized

一 概述 在前面我們說到執行緒安全性問題解決的核心就是同步,同步的核心就是保證原子性.在j a之中最早就支援語法層面的同步解決了,並且提供了synchronized的方式解決問題.二 內建鎖 在j a之中每乙個物件都是乙個內建鎖,這個在jvm的體系之中就規定好了.內建鎖的規定也就決定我們可以拿任意的...

執行緒鎖 synchronized

使用 synchronized解決執行緒同步問題相比較nslock要簡單一些,日常開發中也更推薦使用此方法。首先選擇乙個物件作為同步物件 一般使用self 然後將 加鎖 爭奪資源的讀取 修改 放到 塊中。synchronized中的 執行時先檢查同步物件是否被另乙個執行緒占用,如果占用該執行緒就會處...

執行緒之 鎖 synchronized鎖

多執行緒中有寫程式是由一寫bug的,學習執行緒鎖,很經典的例子,買票案例 有a,b,c三個視窗,同時售賣100張票,最後可能會出現賣了重複的票,或者多賣了,賣超了等執行緒不安全問題 看乙個執行緒不安全的賣票 小明,小張,小王同時去買票,就會出現上面的執行緒不安全問題,因為,視窗1賣了1張票,而另外兩...