https://www.cnblogs.com/c-lover/p/10740183.html
java中安全的單例與不安全的單例
1.內部靜態類(安全的)
public class Singleton {
private static class SingletonHolder{
private final static Singleton instance=new Singleton();
}
public static Singleton getInstanceStaticInnerClass(){
return SingletonHolder.instance;
}
}
2.餓漢模式(安全的)
利用靜態類的加載構成的天然線程安全的單例
這就是飢餓模式,不管是否用到都創建對象,如果對象太大會造成內存浪費。
public class Singleton {
private static Singleton safeSingleton=null;
static {
safeSingleton=new Singleton();
}
public static Singleton getInstanceSafe(){
return safeSingleton;
}
}
3.懶漢模式(不安全)
因爲餓漢模式在對象不被使用時會浪費內存,因此可以在使用時再創建對象。
但是在多線程中不安全,因爲在new時對象具有不可見性
public class Singleton {
private static Singleton singleton=null;
private Singleton(){
}
public static Singleton getInstanceSimpleLazy(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
4.雙檢鎖(不安全)
//雙檢鎖
//雙檢鎖的問題:多線程中可能會返回一個未被初始化完畢的對象。
//原因:初始化對象的步驟是 1.爲對象分配內存 2.初始化對象 3.將對象指向singleton
//由於2依賴於1,1,2不會被重排序。2,3沒有依賴性可能會被重排序。也就是說可能會先將一個null的對象指向singleton,而此時該對象又正在被初始化。
//假設此時另外一個線程來訪問singleton,那麼就會返回一個null對象
public class Singleton {
private static Singleton singleton=null;
private static Object ob=new Object();
private Singleton(){
}
public static Singleton getInstanceDoubleCheck(){
if(singleton==null){
synchronized(ob){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
5.枚舉(安全的,建議使用)
調用方法:Factory.INSTANCE.getResource
INSTANCE: 是被static final聲明瞭的Factory 的實例。
enum的申明: public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable
class Resource{
}
public enum Factory{
INSTANCE;
private Resource resource;
Factory(){
resource=new Resource();
}
public Resource getResource(){
return resource;
}
}
標籤: 單例模式 java 安全於不安全