您的位置:首页 > 其它

学习设计模式——单例模式

2015-08-10 15:50 381 查看
适用于:

程序中最多只有该类的一个实例,并提供一个全局访问点

如:缓存、线程池、偏好设置对象、打印机等设备驱动程序、日志对象等

优点:

减少内存开支,尤其在创建或销毁频繁使用的对象时。

避免对资源多重占用,比如写文件

设置全局访问点,优化和共享资源访问

缺点:

没有接口,难扩展,因为其要求“自身实例化”,所以接口或抽象类都是没有意义的。

对测试也不利

单例模式与单一职责原则有冲突。

单例模式入门:

1.懒汉式

public class Singleton {
private static Singleton uniqueInstance = null;

private Singleton() {
}

public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}


2.饿汉式

public class Singleton {
private static Singleton uniqueInstance = new Singleton();

private Singleton() {
}

public static Singleton getInstance() {
return uniqueInstance;
}
}


懒汉式用时间换空间,没有人使用就不会创建实例。

饿汉式用空间换时间,不管用不用都创建。

单例模式进阶:

懒汉式进阶——双重检查加锁

懒汉式如果不加synchronized关键字的话是线程不安全的。

而饿汉式是线程安全。

如果在创建实例的方法上加synchronized关键字能使得线程安全,但是会影响性能,而通过双重检查加锁可以减少性能的影响。

public class Singleton {
// volatile 只适用于jkd1.5及以上,而且会屏蔽一些优化代码,所以运行效率不高,没有特别需要不要轻易使用。
private volatile static Singleton uniqueInstance = null;

private Singleton() {
}

public static Singleton getInstance() {
if (uniqueInstance == null) {
// 第一次创建时同步,以后就不需要同步了
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}


饿汉式进阶——Initialize-on-demand Holder Class idiom

public class Singleton {
//用静态的内部类,是线程安全的
private static class SingletonHolder {
// 在内部类创建实例,由于是静态实例,所以是唯一的
private static Singleton instance = new Singleton();
}

private Singleton() {
}

public static Singleton getInstance() {
return SingletonHolder.instance;
}
}


单例模式最佳实现——枚举

public enum Singleton {
uniqueInstance;
}


用枚举实现单例模式简洁、高效、安全

单例模式扩展:

控制实例的数量

public class Singleton {
private static int maxNum = 2;
private static int index = 0;
private static Vector<Singleton> vector = new Vector<Singleton>();
static {
for (int i = 0; i < maxNum; i++) {
vector.add(new Singleton());
}
}

private Singleton(){
}

public static Singleton getInstance(){
Random random = new Random();
index = random.nextInt(maxNum);
return vector.get(index);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: