单例模式
单例模式是一种对象创建型模式
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
一、优点
- 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
- 保持程序运行的时候该中始终只有一个实例存在内存中。
二、三要素
- 实例唯一性
- 自行创建
- 全局访问
public class Singleton {
private static volatile Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance(){
if (singleton ==null){
synchronized (Singleton.class){
if (singleton ==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
二、要保证单例,需要做到以下几步
- 必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
- 必须定义一个静态函数获得该单例
- 单例使用volatile修饰
- 使用synchronized进行同步处理,并且双重判断是否为null,我肯看到synchronized(Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否为null是必须的
- 由于多线程的情况,系统会根据代码自动调用“指令重排”机制,但是正是由于这个机制,导致了普通的双端检锁不能很好的达到线程安全的效果,所以此时需要利用Volatile的特性。
- 核心就是利用Volatile关键字防止“指令重排”,再利用双端检锁来达到线程安全。
三、android中常用的单例模式
1.比如Android-Universal-Image-Loader中的单例
private volatile static ImageLoader instance;
/** Returns singleton class instance */
public static ImageLoader getInstance() {
if (instance == null) {
synchronized (ImageLoader.class) {
if (instance == null) {
instance = new ImageLoader();
}
}
}
return instance;
}
2.EventBus中的单例
private static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
3.管理activity单例
public class ActivityManager {
private static volatile ActivityManager instance;
private Stack<Activity> mActivityStack = new Stack<Activity>();
private ActivityManager(){
}
public static ActivityManager getInstance(){
if (instance == null) {
synchronized (ActivityManager.class) {
if (instance == null) {
instance = new ActivityManager();
}
}
return instance;
}
public void addActicity(Activity act){
mActivityStack.push(act);
}
public void removeActivity(Activity act){
mActivityStack.remove(act);
}
public void killMyProcess(){
int nCount = mActivityStack.size();
for (int i = nCount - 1; i >= 0; i--) {
Activity activity = mActivityStack.get(i);
activity.finish();
}
mActivityStack.clear();
android.os.Process.killProcess(android.os.Process.myPid());
}
}
推荐链接单例模式