设计模式——单例模式

场景

在学习Mybatis或者Hibernate中,有一个SqlSessionFactory对象。此对象属于重量级对象,消耗的资源比较大,也只需要存在一个即可。类似的对象还有,线程池、缓存、日志等。这种情况下,就可以使用单例模式来进行控制对象的创建,确保只存在一个。

饿汉模式

懒汉的的单例模式顾名思义就是,在使用前就已经完成的初始化。
代码:

public class HungrySingleton {

    //类装载时就完成初始化
    private static HungrySingleton hungrySingleton = new HungrySingleton();

    //申明私有的构造方法,无法外部通过new初始化对象
    private HungrySingleton() {

    }

    public static HungrySingleton getSingleton() {
        System.out.println("获取单例对象");
        return HungrySingleton.hungrySingleton;
    }
}

这样的写法很简单,但由于在类装载时就完成了初始化,可能会造成一定的资源浪费,但是不存在多线程的问题,比较常见。

懒汉模式

饿汉模式是在类装载的时候就完成了初始化,懒汉模式在被调用的时候才进行初始化,不会造成内存的浪费问题。
代码:

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的构造方法,无法外部通过new初始化对象
    private LazySingleton() {

    }

    public static LazySingleton getLazySingleton() {
        //多线程中,可能出现问题,导致多次初始化
        if (lazySingleton == null) {
            System.out.println("完成懒汉加载");
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

在多线程中,一个线程准备创建一个对象,这时另一个线程进入if条件判断中,此时对象还未创建,两个线程都将创建对象。

懒汉—Version2.0

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的构造方法,无法外部通过new初始化对象
    private LazySingleton() {

    }

    //同步
    public static synchronized LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            System.out.println("完成懒汉加载");
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

一整个方法加上synchronized 进行同步,对性能而言会存在很大的问题,再进一步改进。

懒汉—Version3.0

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的构造方法,无法外部通过new初始化对象
    private LazySingleton() {

    }

    //同步
    public static synchronized LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            synchronized (LazySingleton.class) {
                if (lazySingleton == null) {
                    System.out.println("完成懒汉加载");
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

需要对对象进行双重检查才能保证在多线程下,不会创建多个对象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章