餓漢式2種(靜態常量餓漢式、靜態代碼塊餓漢式)
懶漢式3種(線程不安全懶漢式、線程安全懶漢式、同步代碼塊懶漢式)
還有3種(雙重檢查、靜態內部類、枚舉方式)
// 1.靜態常量餓漢式
public class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
優點:實現較為簡單,在類加載時就完成了實例化,避免了多線程同步問題
缺點:在類加載時就完成了實例化(使類加載的情況有很多種,不一定是調用getInstance()方法使類進行加載的),沒有達到懶加載的效果。如果程序從始至終未用到該實例,則造成了空間浪費
//2.靜態代碼塊餓漢式
public class Singleton{
private static Singleton singleton;
static{
singleton = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
優缺點:同靜態常量餓漢式
//3.線程不安全懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優缺點:起到懶加載的效果,但是只適合在單線程下使用(開發中不推薦使用)
//4.線程安全懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優點:起到懶加載的效果,線程安全
缺點:調用效率低(開發中不推薦使用)
//5.同步代碼塊懶漢式
public class Singleton{
private Singleton(){}
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
singleton = new Singleton();
}
}
return singleton;
}
}
優點:懶加載
缺點:不適合多線程環境,可能因多個線程同時到達if(singleton == null)而產生多個實例,表面代碼看線程安全實際線程不安全
//6.雙重檢查(推薦使用)
public class Singleton{
private Singleton(){}
private static volatile Singleton singleton;
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
優點:解決了同步代碼塊方式的線程安全問題
//7.靜態內部類(推薦使用)
靜態內部類的特點:
1.當外部類被裝載時,靜態內部類不會被立即裝載
2.當調用getInstance()時靜態內部類只被裝載一次
public class Singleton{
private Singleton(){}
private static class SingletonInstance{
private static final Singleton singleton = new Singleton();
}
public static Singleton getInstance(){
return SingletonInstance.singleton;
}
}
優點:當外部類Singleton被裝載時,靜態內部類不會立即被裝載,而是在需要時才被裝載,也就是調用getInstance()時才被裝載,達到了懶加載的效果,這種方式采用了類加載機制來保證初始化實例時只有一個線程,所以在這里JVM
//8.枚舉方式(推薦使用)
enum Singleton{
INSTANCE;
public void method(){
// 操作方法
}
}
優點:線程安全,效率高,還可防止反序列化重新創建新的對象
單例模式的應用場景:
需要被頻繁創建或銷毀的對象
創建對象時耗時或者耗費資源過多(即重量級對象),但又經常使用的對象
頻繁訪問的數據庫或文件