面試題之併發相關專欄一

一、Synchronized用過麼?其原理是什麼?

Synchronized是由JVM虛擬機實現的一種實現互斥同步的方式,被Synchronized修飾後的程序塊編譯後的字節碼文件中,在編譯前後被編譯器生成了monitorenter和monitorexit兩個字節碼指令。

  • 在虛擬機執行到monitorenter指令時,首先要嘗試獲取對象的鎖,如果這個對象沒有鎖定,或者當前線程已經擁有了這個對象的鎖,把鎖的計數器加1;
  • 當執行到monitorexit指令時將鎖的計數器減1;
  • 當計數器爲0時,鎖就被釋放了。如果獲取對象失敗了,那當前線程就要阻塞等待,一直到其他線程釋放鎖爲止,Java中Synchronized是通過在對象頭設置標記,達到了獲取鎖和釋放鎖的目的;

二、什麼是可重入性,爲什麼說Synchronized是可重入鎖?

可重入性是鎖的一個基本要求,是爲了解決自己鎖死自己的情況。如果一個類中的同步方法method2調用另一個同步方法method1 ,假如 Synchronized 不支持重入,進入 method2 方法時當前線程獲得鎖,method2 方法裏面執行 method1 時當前線程又要去嘗試獲取鎖,對 Synchronized 來說,可重入性是顯而易見的,在執行 monitorenter 指令時,如果這個對象沒有鎖定,或者當前線程已經擁有鎖時如果不支持重入,它就要等其他線程釋放鎖,而把自己阻塞,導致自己鎖死自己。有了這個對象的鎖(而不是已擁有了鎖則不能繼續獲取),就把鎖的計數器 +1,其實本質上就通過這種方式實現了可重入性。

三、爲什麼說Synchronized是非公平鎖?

非公平主要表現在獲取鎖的行爲上,並非是按照申請鎖的時間先後順序給等待的線程分配鎖資源,每當有線程使用鎖後,由CPU調度,每一個線程都有機會競爭獲取鎖資源,包括剛剛釋放鎖的線程,也有可能再次獲取這個鎖對象,並不是隊列中等待最久的線程就獲取到鎖。這樣做的目的是爲了提高執行性能,缺點就是可能會產生線程飢餓現象。

四、請談談可重入鎖的原理?

每一個鎖關聯一個線程持有者和計數器。

  • 當計數器爲 0 時表示該鎖沒有被任何線程持有,那麼任何線程都可能獲得該鎖而調用相應的方法;
  • 當某一線程請求成功後,JVM會記下鎖的持有線程,並且將計數器置爲 1,此時如果其它線程請求鎖資源,則必須阻塞等待;而該持有鎖的線程如果再次請求這個鎖,就可以再次拿到這個鎖,同時計數器會遞增;當線程退出同步代碼塊時,計數器會遞減,如果計數器爲 0,則釋放該鎖。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章