兩個線程對初始值為 0 的靜態(tài)變量一個做自增,一個做自減,各做 5000 次,結(jié)果是 0 嗎?public class SyncDemo {
【注意】
雖然 java 中互斥和同步都可以采用 synchronized 關(guān)鍵字來完成,但它們還是有區(qū)別的:
分類 | 具體分類 | 被鎖的對象 | 偽代碼 |
方法 | 實例方法 | 類的實例對象 | public synchronize void method(){} |
靜態(tài)方法 | 類對象 | public static synchronize void method(){} | |
代碼塊 | 實例對象 | 類的實例對象 | synchronize(this){} |
class對象 | 類對象 | synchronize(SynchronizeDemo.class){} | |
任意實例對象object | 實例對象object | // String 對象作鎖String lock = "";synchronize(lock){} |
在獲取鎖時,是將當(dāng)前線程插入到cxq的頭部,而釋放鎖時,默認(rèn)策略(QMode=0)是:如果EntryList為空,則將cxq中的元素按原有順序插入到EntryList,并喚醒第一個線程,也就是當(dāng)EntryList為空時,是后來的線程先獲取鎖。_EntryList不為空,直接從_EntryList中喚醒線程對象內(nèi)存布局&對象頭詳解
每個class對象會有一個對應(yīng)的epoch字段,每個處于偏向鎖狀態(tài)對象的Mark Word中也有該字段,其初始值為創(chuàng)建該對象時class中的epoch的值。每次發(fā)生批量重偏向時,就將該值+1,同時遍歷JVM中所有線程的棧,找到該class所有正處于加鎖狀態(tài)的偏向鎖,將其epoch字段改為新值。下次獲得鎖時,發(fā)現(xiàn)當(dāng)前對象的epoch值和class的epoch不相等,那就算當(dāng)前已經(jīng)偏向了其他線程,也不會執(zhí)行撤銷操作,而是直接通過CAS操作將其Mark Word的Thread Id 改成當(dāng)前線程Id。
歡迎光臨 愛鋒貝 (http://m.7gfy2te7.cn/) | Powered by Discuz! X3.4 |