在Java1.6以後,jvm對於synchronized進行了大量的優化,app
鎖消除:鎖消除是JIT編譯器對synchronized鎖作的優化,在編譯的時候,JIT會經過逃逸分析技術,來分析synchronized鎖對象jvm
鎖粗化:這個意思就是,JIT編譯器若是發現有代碼裏連續屢次加鎖和釋放鎖的代碼,會給合併爲一個鎖,就是鎖粗化,把一個鎖給搞粗了,避免頻繁屢次加鎖釋放鎖性能
偏向鎖:monitorenter和monitorexit是要使用CAS操做加鎖和釋放鎖的,開銷較大,所以若是發現大機率只有一個線程會主要競爭一個鎖,優化
那麼會給這個鎖維護一個偏好(Bias),後面他加鎖和釋放鎖,基於Bias來執行,不須要經過CAS線程
輕量級鎖:若是偏向鎖沒能成功實現,就是由於不一樣線程競爭鎖太頻繁了,此時就會嘗試採用輕量級鎖的方式來加鎖,就是將對象頭的Mark Word裏有一個輕量級鎖指針,指針
嘗試指向持有鎖的線程,而後判斷一下是否是本身加的鎖對象
自適應性鎖: 也叫自旋鎖,當其餘線程獲取鎖未成功時,不切換線程,自旋一會,等待你這個鎖釋放,減小上下文切換帶來的性能消耗事件
happen-before原則:即規定了在某些條件下,不容許編譯器、指令器對你寫的代碼進行指令重排,以此來保證有序性編譯器
1.程序次序規則:一個線程內,按照代碼順序,書寫在前面的操做先行發生於書寫在後面的操做it
2.鎖定規則:一個unLock操做先行發生於後面對同一個鎖的lock操做,好比說在代碼裏有先對一個lock.lock(),lock.unlock(),lock.lock()
3.volatile變量規則:對一個volatile變量的寫操做先行發生於後面對這個volatile變量的讀操做,volatile變量寫,再是讀,必須保證是先寫,再讀
4.傳遞規則:若是操做A先行發生於操做B,而操做B又先行發生於操做C,則能夠得出操做A先行發生於操做C
5.線程啓動規則:Thread對象的start()方法先行發生於此線程的每一個一個動做,thread.start(),thread.interrupt()
6.線程中斷規則:對線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生
7.線程終結規則:線程中全部的操做都先行發生於線程的終止檢測,咱們能夠經過Thread.join()方法結束、Thread.isAlive()的返回值手段檢測到線程已經終止執行
8.對象終結規則:一個對象的初始化完成先行發生於他的finalize()方法的開始