xl_echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微信號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這纔是真正的堪稱強大!!java
參考文章列表:編程
Java併發編程:Synchronized底層優化(偏向鎖、輕量級鎖)安全
偏向鎖、輕量級鎖、重量級鎖、自旋鎖原理講解(推薦看一下)多線程
參考視頻:咕泡學院Mic老師的多線程基本原理併發
若是業務代碼邏輯當中,有一個操做須要改變一個常量的值,好比int i = 0, 業務代碼當中i須要i++。單線程的狀況下,不會出現問題,若是是多線程併發操做i的值,這個時候,i的結果最終是什麼?會出現線程的安全問題。這種狀況應該怎麼解決?佈局
在java當中Synchronized是一種同步鎖,也是一種互斥鎖,當有一個線程拿到這個鎖的時候,其餘的線程就拿不到。在jdk1.6之前Synchronized是重量鎖,以後作了相關優化,性能有必定的提高。性能
Synchronized鎖的存儲學習
鎖的狀態總共有四種:無鎖狀態、偏向鎖、輕量級鎖和重量級鎖。隨着鎖的競爭,鎖能夠從偏向鎖升級到輕量級鎖,再升級的重量級鎖(可是鎖的升級是單向的,也就是說只能從低到高升級,不會出現鎖的降級)。JDK 1.6中默認是開啓偏向鎖和輕量級鎖的,咱們也能夠經過-XX:-UseBiasedLocking來禁用偏向鎖。鎖的狀態保存在對象的頭文件中,以32位的JDK爲例:優化
鎖狀態 | 25bit | 4bit | 1bit | 2bit | |
23bit | 2bit | 是否偏向鎖(是否禁用偏向) | 鎖標誌位 | ||
無鎖態 | 對象的hashCode | 分代年齡 | 0 | 01 | |
輕量級鎖 | 指向棧中鎖記錄的指針 | 00 | |||
重量級鎖 | 指向互斥量(重量級鎖)的指針 | 10 | |||
GC標記 | 空 | 11 | |||
偏向鎖 | 線程ID | Epoch | 分代年齡 | 1 | 01 |
這些鎖不等同於Java API中的ReentratLock這種鎖,這些鎖是概念上的,是JDK1.6中爲了對synchronized同步關鍵字進行優化而產生的的鎖機制。這些鎖的啓動和關閉策略能夠經過設定JVM啓動參數來設置,固然在通常狀況下,使用JVM默認的策略就能夠了。
通俗的講,偏向鎖就是在運行過程當中,對象的鎖偏向某個線程。即在開啓偏向鎖機制的狀況下,某個線程得到鎖,當該線程下次再想要得到鎖時,不須要再得到鎖(即忽略synchronized關鍵詞),直接就能夠執行同步代碼,比較適合競爭較少的狀況。
輕量級鎖不是用來替代傳統的重量級鎖的,而是在沒有多線程競爭的狀況下,使用輕量級鎖可以減小性能消耗,可是當多個線程同時競爭鎖時,輕量級鎖會膨脹爲重量級鎖。
即當有其餘線程佔用鎖時,當前線程會進入阻塞狀態。
wait:釋放鎖,阻塞線程notify:喚醒一個線程