JAVA设计模式----单例模式

来源:互联网 发布:爱知流量计 编辑:程序博客网 时间:2024/06/01 08:51
单例模式(懒汉模式、饿汉模式):保证整个应用程序中某个实例有且只有一个。

饿汉模式:所谓饿汉模式就是说在程序在加载类时就已经进行了对象的实例化的,也就是说程序调用两次类方法就实例化两次(实例化对象指向相同的内存块)。
过程:
1.将构造方法私有化,不允许外部直接创建对象
2.创建类的唯一实例,private static 修饰
3.提供一个用于获取实例的方法,使用public static 修饰

懒汉模式:所谓的懒汉模式是说在程序加载类时没有第一时间进行对象的实例化。
过程:
1.将构造方法私有化,不允许外部直接创建对象
2.创建类的唯一实例,private static 修饰,只是声明,没有进行实例化
3.提供一个用于获取实例的方法,使用public static 修饰,判断对象是否实例化,如果没有则进行实例化。

详情解析:
一般情况下,我们对于一个对象的创建所使用的方法是new(),就像 XXX xx = new XXX();
但是这样在创建多个对象的情况下会导致内存占用较大的空间。
例子:
/*
 * 在本类中有一个默认的无参构造方法
 */
public class Singleton {

}

/*
 * 测试类
 * 调用构造方法实例化对象并进行比较
 */
public class TestSingleton {
    public static void main(String[] args) {
        Singleton si1 = new Singleton();
        Singleton si2 = new Singleton();
        if(si1 == si2){
            System.out.println("si1 == si2");
        }else{
            System.out.println("si1 != si2");
        }
    }
}
比较结果:si1 != si2
由上面的例子可以看出,通过调用类中的构造方法来进行new()实例化对象时获得的俩个对象所对应的内存块是不同的,所以当多个实例化对象时对于内存小是计算机来说是一个令人头疼的问题。
所以在这里引入“单例模式”。
所谓的单例模式就是保证整个应用程序中某个实例有且只有一个。也就是说Test测试类在创建实例化对象时无论实例化对象的数量是多少,对象所对应的内存块都是一样的。
例子:
/*
 * 单例模式
 */
public class Singleton {
    // 1.将构造方法私有化,不允许外部直接创建对象
    private Singleton(){}
    // 2.创建类的唯一实例,private static 修饰
    private static Singleton singleton = new Singleton();
    // 3.提供一个用于获取实例的方法,使用public static 修饰
    public static Singleton getSingleton(){
        return singleton;
    }
}

/*
 * 测试类
 */
public class TestSingleton {
    public static void main(String[] args) {
        Singleton si1 = Singleton.getSingleton();
        Singleton si2 = Singleton.getSingleton();
        if(si1 == si2){
            System.out.println("si1 == si2");
        }else{
            System.out.println("si1 != si2");
        }
    }
}
比较结果:si1 == si2
通过上面的例子可以很好的解决对于new()实例化对象时内存的分配问题。这就是单例模式中的饿汉模式。

而单例模式中还有一种较为节省的模式,俗称懒汉模式。
懒汉模式顾名思义就是比较“懒”,他没有在创建对象时第一时间进行对象的实例化,分配内存空间。它的思想是在类中创建实例后,程序调用类方法时,如果发现类中的对象尚未实例化时则new()一个实例化对象出来。
例子:
/*
 * 单例模式
 */
public class Singleton2 {
    //1.将构造方法私有化,不允许外部直接创建对象
    private Singleton2(){}
    //2.创建类的唯一实例,private static 修饰,只是声明,没有进行实例化
    private static Singleton2 singleton;
    //3.提供一个用于获取实例的方法,使用public static 修饰,判断对象是否实例化,如果没有则进行实例化。
    public static Singleton2 getSingleton(){
        if(singleton == null){
            singleton = new Singleton2();
        }
        return singleton;
    }
}


/*
 * 测试类
 */
public class TestSingleton {
    public static void main(String[] args) {
        Singleton si1 = Singleton.getSingleton();
        Singleton si2 = Singleton.getSingleton();
        if(si1 == si2){
            System.out.println("si1 == si2");
        }else{
            System.out.println("si1 != si2");
        }
    }
}
比较结果:si1 == si2
通过上面的例子可以看出懒汉模式的"懒"的体现地方了。。。


二者的区别:
饿汉模式:由于类在加载时就已经实例化了对象,所以在加载的过程较为缓慢,但是由于对象已经实例化好了,所以在运行是比较快,而且相对来说线程是安全的。
懒汉模式:由于类在加载时没有对对象进行实例化,而是要等到运行时判断无实例化对象时才进行对象的实例化,所以在加载的过程较块,但是由于没有提前实例化对象的原因 ,所以在运行是比较慢,而且相对来说线程是不安全的。

1 0