public class Singleton {
? private Singleton() {}
? private static class SingletonHolder{
? ? private static final Singleton instance = new Singleton();
? }
?
? public static Singleton getInstance() {
? ? return SingletonHolder.instance;
? }
}
1.為什么是線程安全的
前置知識:類加載時會對靜態(tài)變量進(jìn)行初始化,類加載是線程安全的
只有在用到這個類的時候才會觸發(fā)類的加載,例如:創(chuàng)建類對象,創(chuàng)建子類對象,調(diào)用靜態(tài)方法,調(diào)用靜態(tài)變量,反射創(chuàng)建對象,這幾種情況下時jvm會將類加載到方法區(qū)。同時外部類加載不會導(dǎo)致內(nèi)部類加載。
當(dāng)調(diào)用singlentone類的getinstance靜態(tài)方法時會觸發(fā)jvm加載sigletone類,靜態(tài)方法中調(diào)用了sigletoneholder類的靜態(tài)變量,觸發(fā)jvm加載holder類,同時會初始化instance靜態(tài)變量,創(chuàng)建tone類對象,由于tone對象創(chuàng)建是在類加載過程中所以是線程安全的
2.為什么滿足延遲加載
只有第一次調(diào)用tone類的getinstance方法時才會創(chuàng)建instance類對象,因此滿足延遲加載。再以后調(diào)用方法時由于類已經(jīng)加載完成,靜態(tài)變量也已經(jīng)初始化完成,因此不會再重復(fù)執(zhí)行靜態(tài)變量初始化操作,以后返回的都是同一個對象
3.是否可以設(shè)置為普通內(nèi)部類
不可以,因為普通內(nèi)部類不能包含靜態(tài)變量和靜態(tài)方法,因此就不能在類加載時進(jìn)行初始化,會出現(xiàn)線程安全問題
4.為什么holder是private而不是public
因為holder只在stone外部類調(diào)用,外部類之外不需要調(diào)用因此設(shè)置為private