java中安全的单例与不安全的单例

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;
} }
上一篇:python提示AttributeError: 'NoneType' object has no attribute 'append'【转发】


下一篇:JAVA的序列化和持久化的区别与联系