在平常的項目開發中,經常會遇到一個類有且只有一個實例的狀況,這就是典型的單例模式。安全
關於單例模式的設計有三種思路:多線程
思路一:併發
1.構造方法私有;高併發
2.聲明全局的私有的靜態的類的對象爲null;性能
3.提供公有的靜態的getInstance方法,判斷對象是否爲空,若爲空,則建立對象,不然,直接返回對象;spa
public class Singleton{線程
private Singleton(){}設計
private static Singleton singletonObject ;對象
public static synchronized Singleton getInstance(){ssl
return singletonObject = singletonObject == null?new Singleton():singletonObject ;
}
}
優勢:類加載的時候不會加載實例對象,延遲加載,類加載速度快;
缺點:但線程須要等待,前一個線程鎖釋放後下一個才能操做,若是高併發且對性能要求高的, 這種設計效果可能不理想。
思路二:
1.構造方法私有
2.直接實例化全局的私有的靜態的類的對象
3.提供公有的靜態的getInstance方法,只有調用此方法即返回實例對象
public class Singleton{
private Singleton(){}
private static Singleton singletonObject = new Singleton();
public static Singleton getInstance(){
return singletonObject ;
}
}
優勢:類加載的時候實例對象,獲取對象速度快。線程安全,避免了多線程的同步問題,不用加線程鎖;
缺點:不具有延遲加載,類加載速度慢。此外,若是在類中還有其餘靜態方法或屬性,調用時也會實例化對象,而這不是咱們期待的
思路三:
1.構造方法私有
2.聲明全局的私有的靜態的類的對象爲null
3.提供靜態的內部類,在內部類中聲明類的實例對象
4.提供公有的靜態的getInstance方法,調用內部類的已實例化的對象
public class Singleton{
private Singleton(){}
private static Singleton singletonObject;
public static class SingletonHelper{
private static final Singleton INSTANCE= new Singleton ();
}
public static Singleton getInstance(){
singletonObject = SingletonHelper.INSTANCE
return singletonObject ;
}
}
優勢:既達到了延遲加載的效果也線程安全,同時避免了線程同步下降性能的問題
備註:調用類的構造方法或靜態成員時會classloader,在單例模式中,構造器已經私有,只有調用靜態方法或屬性纔會classloader