设计模式篇之单例(一)

单例模式是最简单的设计模式之一。当某个类只需要一个实例时,我们可以用这种模式,比如数据库的连接,可以提高效率,避免资源浪费。

单例设计模式可分为懒汉和饿汉两种模式。

1、饿汉:

public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return singleton;
    }
}

之所以被称为饿汉式,是因为在类加载的时候,就初始化了所需要的唯一实例。这是一种最简单的实现方式,构造函数的private属性保证了该类不会再有第二个实例。由于类被加载的时候,就已经有了该事例,所以这种实现方式是线程安全的。

2、懒汉式

public class Singleton2 {
    private Singleton2(){}
    private static Singleton2 singleton2 = null;
    public static Singleton2 getInstance(){
        if(singleton2 == null){
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}

区别于饿汉式,懒汉式只有在被使用的时候,才会产生唯一的实例。但因此也产生了另一个问题,在修改singleton2的时候,可能会受到访问对象数量和访问速度的影响,而出现多个实例的状况,所以说是线程不安全的。

3、懒汉式2.0

public class Singleton2 {
    private Singleton2(){}
    private static Singleton2 singleton2 = null;
    public static synchronized Singleton2 getInstance(){
        if(singleton2 == null){
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}

将获取实例的方法加上同步,使之成为同步函数,对内部资源进行互斥访问,便可解决线程不安全的问题。但随之而来的新问题,也需要解决一下,那就是效率问题。

4、懒汉式3.0

public class Singleton2 {
    private Singleton2(){}
    private static Singleton2 singleton2 = null;
    public static Singleton2 getInstance(){
        if(singleton2 == null){
            synchronized (Singleton2.class){
                if(singleton2 == null){
                    singleton2 = new Singleton2();
                }
            }
        }
        return singleton2;
    }
}

注意到,如果使用同步函数,那么将会对内部所有代码上锁,意味着每次调用该实例,都要判断一下,效率很低。然而真正要考虑线程安全的地方仅仅是初始化实例的时候。所以为了提高效率,在锁代码块之前,先判断一下需不需要new实例,即是不是第一次访问。这样,大部分情况下不需要进同步块,提高了效率。

如有错误,欢迎批评指正。

posted @ 2019-06-04 13:22  小楼夜听雨QAQ  阅读(178)  评论(0编辑  收藏  举报