閱讀本文的讀者,須要對Java輕量級鎖有必定的瞭解,知道lock record, mark word之類的名詞。能夠參考個人一篇博文:Java輕量級鎖原理詳解(Lightweight Locking) 多線程
Java偏向鎖(Biased Locking)是Java6引入的一項多線程優化。它經過消除資源無競爭狀況下的同步原語,進一步提升了程序的運行性能。 性能
輕量級鎖也是一種多線程優化,它與偏向鎖的區別在於,輕量級鎖是經過CAS來避免進入開銷較大的互斥操做,而偏向鎖是在無競爭場景下徹底消除同步,連CAS也不執行(CAS自己仍舊是一種操做系統同步原語,始終要在JVM與OS之間來回,有必定的開銷)。 優化
所謂的無競爭場景,舉個例子,就是單線程訪問帶同步的資源或方法。 spa
偏向鎖,顧名思義,它會偏向於第一個訪問鎖的線程,若是在接下來的運行過程當中,該鎖沒有被其餘的線程訪問,則持有偏向鎖的線程將永遠不須要觸發同步。
若是在運行過程當中,遇到了其餘線程搶佔鎖,則持有偏向鎖的線程會被掛起,JVM會嘗試消除它身上的偏向鎖,將鎖恢復到標準的輕量級鎖。(偏向鎖只能在單線程下起做用) 操作系統
經過下圖能夠更直觀的理解偏向鎖: 線程
這張圖,省略了輕量級鎖相關的幾處步驟,將關注點更多地聚焦在偏向鎖的狀態變化上。
偏向模式和非偏向模式,在下面的mark word表中,主要體如今thread ID字段是否爲空。 圖片
掛起持有偏向鎖的線程,這步操做相似GC的pause,但不一樣之處是,它只掛起持有偏向鎖的線程(非當前線程)。 內存
在搶佔模式的橙色區域說明中有提到,指向當前堆棧中最近的一個lock record(在輕量級鎖原理一文有講到,lock record是進入鎖前會在stack上建立的一分內存空間)。
這裏提到的最近的一個lock record,其實就是當前鎖所在的stack frame上分配的lock record。
整個步驟是從偏向鎖恢復到輕量級鎖的過程。 資源
在JDK6中,偏向鎖是默認啓用的。它提升了單線程訪問同步資源的性能。
但試想一下,若是你的同步資源或代碼一直都是多線程訪問的,那麼消除偏向鎖這一步驟對你來講就是多餘的。事實上,消除偏向鎖的開銷仍是蠻大的。 get
因此在你很是熟悉本身的代碼前提下,大可禁用偏向鎖 -XX:-UseBiasedLocking 。