#define barrier() __asm__ volatile("lwsync")
volatile T* pInst = 0; //volatile關(guān)鍵字阻止編譯器為了優(yōu)化編譯效率而調(diào)整了該變量的匯編指令順序刮萌,簡(jiǎn)單來說就是禁止進(jìn)行指令重排序涯塔。
T* getInstance()
{
lock();
if (!pInst) //鎖內(nèi)再加一個(gè)條件語句降低lock調(diào)用開銷
{
T* temp = new T();
barrier(); //阻止CPU因優(yōu)化而動(dòng)態(tài)調(diào)度調(diào)整指令順序
pInst = temp;
}
unlock();
return pInst;
}
T* temp = new T();
這一步驟其實(shí)由三小步構(gòu)成:
(1)分配內(nèi)存似踱;
(2)在內(nèi)存位置調(diào)用構(gòu)造函數(shù)分别;
(3)將內(nèi)存地址賦給指針哲戚。
在CPU動(dòng)態(tài)調(diào)度優(yōu)化時(shí),可能發(fā)生改變以上三步順序的情況耙考,從1-2-3
變成了1-3-2
谜喊。如果1-3-2
這種情況發(fā)生了,此時(shí)在(3)
執(zhí)行完后如果外部調(diào)用方緊接著使用pInst
指針去調(diào)用該單例的某個(gè)實(shí)例方法琳骡,而該指針指向的內(nèi)存區(qū)域中的構(gòu)造函數(shù)尚未執(zhí)行完锅论,這個(gè)時(shí)間差就可能造成方法調(diào)用失敗讼溺。
barrier()
的插入就是可以保證temp
在完全執(zhí)行完畢后再執(zhí)行下一步的賦值指令楣号,無論前面是否存在CPU調(diào)整指令順序的情況。