×

单例模式

单例模式-控制实例数目,5种写法 :懒汉,饿汉,双重校验锁,枚举和静态内部类

小星星 小星星 发表于2021-04-14 22:00:42 浏览287 评论0

抢沙发发表评论

单例模式的定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点!

1.懒汉,线程安全

public class Singleton {    
    private static Singleton instance;    
    private Singleton (){}    
    public static synchronized Singleton getInstance() {	
    if (instance == null) {
	    instance = new Singleton();
	}	
        return instance;
    }
}


2.饿汉

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
}


3.静态内部类

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}


4.枚举 

public enum Singleton {
    INSTANCE;    
    public void whateverMethod() {
    }
}


5.双重校验锁(jdk1.5)

public class Singleton {    
    private volatile static Singleton singleton;    
    private Singleton (){}    
    public static Singleton getSingleton() {	
        if (singleton == null) {	    
        synchronized (Singleton.class) {		
        if (singleton == null) {
		    singleton = new Singleton();
		}
	    }
	}	
        return singleton;
    }
}


总结


有两个问题需要注意:

1.如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。

2.如果Singleton实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。

对第一个问题修复的办法是:

private static Class getClass(String classname) throws ClassNotFoundException {   
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();   
      if(classLoader == null)   
         classLoader = Singleton.class.getClassLoader();   
      return (classLoader.loadClass(classname));   
   }   
}

对第二个问题修复的办法是:

public class Singleton implements java.io.Serializable {   
   public static Singleton INSTANCE = new Singleton();   
   protected Singleton() {   
      
   }   
   private Object readResolve() {   
            return INSTANCE;   
      }  
}


参考自https://my.oschina.net/dyyweb/blog/609021



 您阅读本篇文章共花了: 

群贤毕至

访客