标签:设计模式 singleton android 线程安全 单例
单例的实现有两个主流方式,分别是懒汉模式和饿汉模式,他们在实例化的时机和效率方面各有不同
1.懒汉模式
/** * Created by jesse on 15-6-28. */ public class Singleton { private static Singleton instance; private Singleton() {} //一定要有私有构造,要不谈何单例 public static Singleton getInstance(){ if (null == instance){ instance = new Singleton(); } return instance; } }
这个时候很多小伙伴要说了,你这个懒汉单例有问题,有线程安全问题.当然这个方式是线程不安全的,当两个线程A和B并发要获取实例的时候,instance还没有被初始化,假设A先拿到时间片去初始化instance,当instance还没有初始化完成的时候,时间片让给了B,这时由于instance还没有被初始化完成那么instance还为空,所以B还会去把instance实例化一次,最终的结果就是instance被实例化了两次.这可能会造成很严重的后果,解决方式就是加锁(牺牲一些性能),使用饿汉模式.
给getInstance方法加锁,这种加锁方式可以解决线程安全问题,但是每次外部对象要获取实例的时候都要进行线程锁定,之后还要再判断instance是否被实例化了,这样在多线程高并发的情况下效率损失就很可观了.
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance(){//给getInstance方法加锁 if (null == instance){ instance = new Singleton(); } return instance; } }
public class Singleton { private static Singleton instance; //private static volatile Singleton instance; 遇到编译器问题时使用 private Singleton() {} public static Singleton getInstance(){ if (null == instance){ synchronized(Singleton.class){ if (null == instance) instance = new Singleton(); } } return instance; } }
2.饿汉模式
饿汉模式是在系统运行起来,在装在类的时候就进行初始化的操作,外部对象使用的时候不需要做任何判断可以直接使用,从效率上来说是优于懒汉模式的.但是对比懒汉模式的延迟加载技术,不管系统用不用该实例,内存都会在最开始的时候创建出来.跟懒汉的时间换空间正好相反,饿汉是空间换时间.
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {}//一定要有私有构造,要不谈何单例 public static Singleton getInstance(){ return instance; } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:设计模式 singleton android 线程安全 单例
原文地址:http://blog.csdn.net/l2show/article/details/46672061