几种常见的Java单例模式写法

实现单利有很多种写法:这里列举几个常见写法,并分析其优劣。

  • 1.懒汉式
  • 缺点:非线程安全。在多线程中,一个线程进入到if判断中,还未来得及执行new 实例操 作,另一个实例也进入了if判断中,那么就会实例化多个对象,造成内存浪费
    	public class Singleton{
    		private Singleton(){};  
    		private static Singleton mInstance ;
    		public static newInstance(){
    			if(mInstance == null){
    				mInstance = new Singleton();
    			}
    			return mInstance;
    		}
    	}
    
  • 2.懒汉式(同步方法)
    • 优点:第一次调用才初始化,避免内存浪费。
    • 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
    	public class Singleton{
    		private staitc Singleton mInstance;
    		private Singleton(){};
    		public static synchronized Singleton new Instance(){
    			if(mInstance == null){
    				mInstance = new Singleton();
    			}
    			return mInstance;
    		}
    	}
    
  • 3.饿汉式,线程安全
    • 优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
    • 缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
    	public class Singleton{
    		private final static Singleton mInstance = new SingleTon();
    		private Singleton(){};
    		public static Singleton newInstance(){
    				return mInstance;
    		}
    	}
    
  • 4.双重校验锁
    • 优点:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
      getInstance() 的性能对应用程序很关键。
    	public class Singleton { 
    		private static volatile Singleton singleton;
    	    private Singleton() {}mInstance
    		public static Singleton getInstance() {
    	        if (mInstance == null) {
    	            synchronized (Singleton.class) {
    	                if (mInstance == null) {
    	                    mInstance = new Singleton();
    	                }
    	            }
    	        }
    	        return mInstance;
    	    }
    	}
    
  • 5.静态内部类
    • 这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
    	public class Singleton {
    		private Singleton() {}
    		private static class SingletonInstance {
    		    private static final Singleton INSTANCE = new Singleton();
    		}	
    		public static Singleton getInstance() {
    		    return SingletonInstance.INSTANCE;
    		}
    	}
    

另外还有枚举方式的写法,因为Android不推荐使用单例,这里不再写出。

你可能感兴趣的:(Java,Android)