首发安卓设计模式,后期会更加仔细。

IO和数据库等都可以使用单例。

1构造函数不对外开发,一般为Private;

2通过一个静态方法或枚举返回单例对象;

3确保单例类对象只有一个,尤其是在多线程中

4确保单例类对象在反序列化是不会重新构建对象。

//懒汉式单例类.在第一次调用的时候实例化自己   
 public class Singleton {  
     private Singleton() {}  
     private static Singleton sing;  
静态工厂方法
     public static  synchronized Singleton getInstance() {  
          if (single == null) {    
              single = new Singleton();  
          }    
         return single;  
     }  
 }

  你可能知道,getInstance()方法中 synchronized关键字,getInstance是一个同步方法,符合了多线程中单例对象一致。但是single即使已经被初始化,每次调用getInstance都会同步进行,消耗了不必要的资源。

DCL单例,其中volatile在之前已经说过了,可以保证无论何时读取这个变量,都是读到内存中最新的值,无论何时写这个变量,都可以立即写到内存中。

public class Singleton {   
     
     /**  
单例对象实例
      */  
     private volatile static Singleton instance = null;   
     
     public static Singleton getInstance() {   
         if (instance == null) {   
             synchronized (Singleton.class) {   
                 if (instance == null) {   
                     instance = new Singleton();   
                 }   
             }   
         }   
         return instance;   
     }   
 }

volatile修饰instance时,在编译后,编译器会自动把第二个判断删除,因为编译器判断这个程序在执行过程中,这个值是不会改变的,编译器不考虑多线程的情况。加了volatile,是告诉编译器,这个变量随时有可能会被其他线程改变,这样编译器就不会把这两个判断优化成一个判断了。

DCL优点:资源利用率高,但是第一次加载反应稍慢,由于Java内存模型原因偶尔失败,在高并发环境也有一定缺陷,虽然几率有点小。

/**
 *内部静态类实现单例模式
 */
 public class Singleton  
 {  
     private Singleton(){ }  
       
     public static Singleton getInstance()  
     {  
         return Nested.instance;       
     }  
       
    //在第一次被引用时被加载  
     static class Nested  
     {  
         private static Singleton instance = new Singleton();  
     }  
       
     public static void main(String args[])  
     {  
         Singleton instance = Singleton.getInstance();  
       
     }  
 }

加载类时不会初始化 instance 只有在第一次调用 Singleton的getInstance()才初始化。这种方式确保线程的安全。

枚举单例

public enum SingIetonEnum{
INSTANCE;
   public void doSomething(){
System.out.println(“do”);
 }
 
 }

写法简单,有自己的方法,创建线程也是安全的。

容器实现单例模式

/**
 * 容器单例模式
  * @author josan_tang
  */
 public class SingIetonManager {
     private static Map<String, Object> objMap = new HashMap<String, Object>();
 
   private SingIetonManager(){}
public static void registerService ( String key,Object instance){
if(!objMap.containsKey (key) ){
objMap.put( key ,instance);
 }
 }
    //根据key从集合中得到单例对象
     public static Object getSingleton(String key) {
         return singletonMap.get(key);
     }
 }

key获取对象对应类型的对象,这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了耦合度。