個(gè)人專題目錄
1.懶加載 線程不安全
當(dāng)被問到要實(shí)現(xiàn)一個(gè)單例模式時(shí),很多人的第一反應(yīng)是寫出如下的代碼,包括教科書上也是這樣教我們的。
public class Singleton {
private static Singleton uniqueInstance;
private Singleton (){}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
這段代碼簡單明了,而且使用了懶加載模式,但是卻存在致命的問題。當(dāng)有多個(gè)線程并行調(diào)用 getInstance() 的時(shí)候,就會(huì)創(chuàng)建多個(gè)實(shí)例。也就是說在多線程下不能正常工作。
2.懶加載 線程安全
為了解決上面的問題,最簡單的方法是將整個(gè) getInstance() 方法設(shè)為同步(synchronized)。
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
雖然做到了線程安全,并且解決了多實(shí)例的問題,但是它并不高效。因?yàn)樵谌魏螘r(shí)候只能有一個(gè)線程調(diào)用 getInstance() 方法。但是同步操作只需要在第一次調(diào)用時(shí)才被需要,即第一次創(chuàng)建單例實(shí)例對(duì)象時(shí)。這就引出了雙重檢驗(yàn)鎖。