(一) 单利设计模式:
保证只有一个实例,并提供一个访问它的全局访问点.
优点:
A,只有一个实例,避免了频繁创建个销毁对象,提高性能.
B,防止其他对象对自己的实例化,确保所有对象都访问这一个实例.
缺点:
A,没有抽象层,扩展优点困难.
适用场景:
A.需要频繁实例化然后销毁的对象。
B.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
C.有状态的工具类对象。
D.频繁访问数据库或文件的对象。
1,饿汉式:
避免了多线程的同步问题,但在类的加载时就完成初始化,类加载较慢,而且没有达到懒加载的效果,会造成内存浪费.不推荐
public class Singleleton {
private static Singleleton instance = new Singleleton();
public Singleleton( ) {}
public static Singleleton getInstance() {
return instance;
}
}
2,懒汉式:
在第一次调用时初始化,虽然节约了资源,但线程不安全.不推荐
public class Singleleton {
private static Singleleton instance;
public Singleleton() {}
public static Singleleton getInstance() {
if(instance == null) {
instance = new Singleleton();
}
return instance;
}
}
3,懒汉式加锁:
线程安全,但每个调用getInstance()方法都要同步,造成不必要的同步开销.不推荐
public class Singleleton {
private static Singleleton instance;
public Singleleton() {}
public static synchronized Singleleton getInstance() {
if (instance == null) {
instance = new Singleleton();
}
return instance;
}
4,双重检查锁:
两次判空,第一次是为了不必要的同步,第二次是在Singleton为null时创建,效率高,资源利用率高.
虽然使用了volatile会影响一点性能,但考虑程序的正确性,牺牲这点值得.
解决了线程安全,资源消耗和多余同步的问题,但有时候会出现失效的问题.也不怎么推荐
private static volatile Singleleton instance;
public Singleleton() {}
public static Singleleton getInstance() {
if (instance == null) {
synchronized (Singleleton.class) {
if(instance == null) {
instance = new Singleleton();
}
}
}
return instance;
}
}
EventBus采用的就是这种创建方式
public class EventBus {
/** Log tag, apps may override it. */
public static String TAG = "EventBus";
static volatile EventBus defaultInstance;
private final int indexCount;
private final Logger logger;
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
5,静态内部类:
第一次加载Singleton类是不会初始化,只有在第一次调用getInstance()方法时,虚拟机才加载SingletonHolder并初始化.
确保了线程安全,也能解决Singleleton唯一性.
推荐使用这种模式.
public Singleleton(){}
public static Singleleton getInstance() {
return SingleletonHolder.instance;
}
public static class SingleletonHolder {
private static final Singleleton instance = new Singleleton();
}
6,枚举:
因为在开发中很少用,也耗内存,可读性不高,自己也没用过,就不介绍了.