摘要:那豈不是線程安全的對于普通同步方法,鎖是當(dāng)前實例對象。如果測試成功,表示線程已經(jīng)獲得了鎖。然后線程嘗試使用將對象頭中的替換為指向鎖記錄的指針。
volatitle
這樣的一行代碼:
volatitle instance = new Singleton(); // instance是volatile變量
匯編后代碼是這樣子的
0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: lock addl $0×0,(%esp);
當(dāng)中有個lock指令,這個指令是做什么的呢?
1)將當(dāng)前處理器緩存行的數(shù)據(jù)寫回到系統(tǒng)內(nèi)存。
2)這個寫回內(nèi)存的操作會使在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)無效。
處理器不會直接跟內(nèi)存打交道,而是緩存。所以,首先會將值寫會內(nèi)存,而后將該值的所有緩存設(shè)置為無效,包括多處理器環(huán)境下的緩存。(那豈不是線程安全的?)
synchronized
對于普通同步方法,鎖是當(dāng)前實例對象。
對于靜態(tài)同步方法,鎖是當(dāng)前類的Class對象。
對于同步方法塊,鎖是Synchonized括號里配置的對象。
由于鎖太重,為了提高syn會采取幾種輕量級鎖
1 偏向鎖
HotSpot的作者發(fā)現(xiàn),鎖總是由同一個線程獲得,因此當(dāng)線程獲得鎖的時候,會在對象頭和棧幀中的鎖記錄里存儲鎖偏向的線程ID,以后該線程在進入和退出同步塊時不需要進行CAS操作來加鎖和解鎖,只需簡單地測試一下對象頭的Mark Word里是否存儲著指向當(dāng)前線程的偏向鎖。如果測試成功,表示線程已經(jīng)獲得了鎖。
如果測試失敗,則需要再測試一下Mark Word中偏向鎖的標識是否設(shè)置成1(表示當(dāng)前是偏向鎖):如果沒有設(shè)置,則使用CAS競爭鎖;如果設(shè)置了,則嘗試使用CAS將對象頭的偏向鎖指向當(dāng)前線程
2 輕量級鎖
線程在執(zhí)行同步塊之前,JVM會先在當(dāng)前線程的棧楨中創(chuàng)建用于存儲鎖記錄的空間,并
將對象頭中的Mark Word復(fù)制到鎖記錄中,官方稱為Displaced Mark Word。然后線程嘗試使用CAS將對象頭中的Mark Word替換為指向鎖記錄的指針。如果成功,當(dāng)前線程獲得鎖,如果失敗,表示其他線程競爭鎖,當(dāng)前線程便嘗試使用自旋來獲取鎖
單例模式可能的問題
double check可能會存在問題
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized(Singleton.class){ if(instance == null) instance = new Singleton();//問題 } } return instance; } }
在問題步驟中,對象的創(chuàng)建包含了三個環(huán)節(jié)
1 分配空間
2 棧指針指向空間
3 實例化對象
但由于jvm的指令重排序,可能1->3->2
那么如果一個線程執(zhí)行完1->3 跳出了syn塊
那么第二個線程判斷實例非空,直接返回,但事實上并沒有初始化掉,因此存在問題
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69979.html
摘要:當(dāng)其他線程調(diào)用時,它們被阻塞,直到第一個線程釋放鎖對象。包關(guān)于獲取這個鎖如果鎖同時被另一個線程擁有則發(fā)生阻塞。所以必須確保沒有其他線程再檢查余額和轉(zhuǎn)賬活動之間修改金額。方法添加一個線程到等待集中,方法解除等待線程的阻塞狀態(tài)。 避免代碼塊受到并發(fā)訪問的干擾 java語言提供了兩種機制實現(xiàn)這種功能 Synchonized 關(guān)鍵字(調(diào)用對象內(nèi)部的鎖) synchronized關(guān)鍵字自動...
摘要:那豈不是線程安全的對于普通同步方法,鎖是當(dāng)前實例對象。如果測試成功,表示線程已經(jīng)獲得了鎖。然后線程嘗試使用將對象頭中的替換為指向鎖記錄的指針。 volatitle這樣的一行代碼: volatitle instance = new Singleton(); // instance是volatile變量 匯編后代碼是這樣子的 0x01a3de1d: movb $0×0,0×1104800...
摘要:的主要功能和關(guān)鍵字一致,均是用于多線程的同步。而僅支持通過查詢當(dāng)前線程是否持有鎖。由于和使用的是同一把可重入鎖,所以線程可以進入方法,并再次獲得鎖,而不會被阻塞住。公平與非公平公平與非公平指的是線程獲取鎖的方式。 1.簡介 可重入鎖ReentrantLock自 JDK 1.5 被引入,功能上與synchronized關(guān)鍵字類似。所謂的可重入是指,線程可對同一把鎖進行重復(fù)加鎖,而不會被阻...
摘要:第一個字被稱為。經(jīng)量級鎖的加鎖過程當(dāng)一個對象被鎖定時,被復(fù)制到當(dāng)前嘗試獲取鎖的線程的線程棧的鎖記錄空間被復(fù)制的官方稱為。根據(jù)鎖對象目前是否處于被鎖定狀態(tài),撤銷偏向后恢復(fù)到未鎖定或經(jīng)量級鎖定狀態(tài)。 Synchronized關(guān)鍵字 synchronized的鎖機制的主要優(yōu)勢是Java語言內(nèi)置的鎖機制,因此,JVM可以自由的優(yōu)化而不影響已存在的代碼。 任何對象都擁有對象頭這一數(shù)據(jù)結(jié)構(gòu)來支持鎖...
摘要:如何在線程池中提交線程內(nèi)存模型相關(guān)問題什么是的內(nèi)存模型,中各個線程是怎么彼此看到對方的變量的請談?wù)動惺裁刺攸c,為什么它能保證變量對所有線程的可見性既然能夠保證線程間的變量可見性,是不是就意味著基于變量的運算就是并發(fā)安全的請對比下對比的異同。 并發(fā)編程高級面試面試題 showImg(https://upload-images.jianshu.io/upload_images/133416...
閱讀 2069·2021-11-11 16:54
閱讀 1050·2021-10-12 10:12
閱讀 389·2019-08-30 15:43
閱讀 654·2019-08-29 13:15
閱讀 1083·2019-08-29 13:12
閱讀 1535·2019-08-26 12:09
閱讀 1663·2019-08-26 10:24
閱讀 2267·2019-08-26 10:15