单例模式以及推荐写法(二)

一、定义

确保一个类只有一个实例,并向整个系统提供这个实例。

二、产生条件

1.构造方法私有化
2.提供一个共有的静态方法,返回该类的一个实例

三、优缺点

优点:
1.减少内存开支,避免反复创建和销毁。
2.只有一个实例,减少系统性能开销,特别是产生一个对象需要比较多的资源时。
3.避免对资源的多重占用,例如写文件动作,只有一个实例存在可以避免对同一个资源文件的同时写操作。
4.单例模式可以在系统设置全局的访问点,优化和共享资源访问。
缺点:
1.单例模式一般无接口,扩展困难。
2.对测试不利,单例类未完成时不能进行测试。
3.与单一职责原则有冲突,单例模式把要单例的业务逻辑融合在一个类中。

四、写法解析

1.懒汉式

class Single {
    private static Single single = null;
    private Single() {
    }
    public static Single getInstance() {
        if (single == null)
            single = new Single();
        return single;
    }
}
实现了懒加载(使用时才创建),但多线程下可能会创建多个实例,高并发场景下不建议使用这个形式,可以添加 synchronized 关键字,例如
class Single {
    private static volatile Single single = null;
    private Single() {
    }
    public static Single getInstance() {
        if (single == null) {
            synchronized (Single.class) {
                if (single == null)
                    single = new Single();
            }
        }
        return single;
    }
}
synchronized 关键字之所以不加在方法上是因为加锁是比较费时的,当访问频繁时可能会拖慢速度,因此放在方法内进行双重判断(双重校验锁)是比较好的做法。volatile 关键字保证了 single 单例的原子性。

2.饿汉式

class Single {
    private static Single single = new Single();
    private Single() {
    }
    public static Single getInstance() {
        return single;
    }
}
完美的解决了高并发场景下可能创建多个实例的问题,不过在类加载时就会进行创建实例,可能你暂时用不到这个实例而造成多余的开销,特别是实例化这个对象需要较多的资源时。
如果这个实例是确定一定会使用到的,建议可以选择使用饿汉式

3.静态内部类

public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
}
既解决了高并发时可能创建多个实例的问题,又避免了饿汉式在类加载时就进行创建实例的问题,实现懒加载。

查看更多:设计模式分类以及六大原则

猜你喜欢

转载自blog.csdn.net/afei__/article/details/80413195
今日推荐