常見的單例模式的實現有五種,其中一種是餓漢式,四種是懶漢式。
- 1.餓漢式:不存線上程安全問題。但不管使不使都會佔用記憶體空間,造成記憶體利用率降低。
package com.zx.singleton;
public class Singleton1 {
private Singleton1(){};
private static Singleton1 instance=new Singleton1();
public static Singleton1 getInstance(){
return instance;
}
}
- 2.懶漢式的第一種:最簡單,存線上程安全問題,不使用。
package com.zx.singleton;
public class Singleton2 {
private Singleton2(){};
private static Singleton2 instance;
public static Singleton2 getInstance(){
if(instance==null){
instance=new Singleton2();
}
return instance;
}
}
- 3.懶漢式的第二種:解決了執行緒安全問題。其中volatile防止重排序,Sychroniezd加鎖。但存在的問題是Sychroniezd加在整個方法上導致執行效率較低。
package com.zx.singleton;
public class Singleton3 {
private Singleton3(){};
private static volatile Singleton3 instance;
public static synchronized Singleton3 getInstance(){
if(instance==null){
instance=new Singleton3();
}
return instance;
}
}
- 4.懶漢式的第三種:不存線上程安全問題。解決了上一種的問題。存在的問題就是加鎖降低效率。
package com.zx.singleton;
public class Singleton4 {
private Singleton4(){};
private static volatile Singleton4 instance;
public static Singleton4 getInstance(){
if(instance==null){
synchronized (Singleton4.class) {
if(instance==null){
instance=new Singleton4();
}
}
}
return instance;
}
}
- 5.懶漢式的第四種:使用靜態內部類,解決執行緒安全問題,同時不使用鎖提高效率。
內部類時延時載入的,也就是在第一次使用時才載入,不使用就不載入,所以可以很好的實現懶漢式單例模式。
package com.zx.singleton;
public class Singleton5 {
private Singleton5(){};
private static class Sub{
private final static Singleton5 instance=new Singleton5();
}
public static Singleton5 getInstance(){
return Sub.instance;
}
}
- 6.列舉實現單例模式
功能完整、使用簡潔、無償地提供了序列化機制、在面對複雜的序列化或者反射攻擊時仍然可以絕對防止多次例項化。
列舉如何保證序列化單例:Java規範中規定,每一個列舉型別極其定義的列舉變數在JVM中都是唯一的,因此在列舉型別的序列化和反序列化上,Java做了特殊的規定。在序列化的時候Java僅僅是將列舉物件的name屬性輸出到結果中,反序列化的時候則是通過 java.lang.Enum 的 valueOf() 方法來根據名字查詢列舉物件(即通過name查詢列舉物件,並未真正對列舉物件做序列化)。
public class EnumSingleton{
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
}
private static enum Singleton{
INSTANCE;
private EnumSingleton singleton;
private Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getInstance(){
return singleton;
}
}
}`