单例设计模式

最近看了《大话设计模式》这本书,想在博客中记下以加深自己的印象。

单例模式概述

顾名思义,单例指的是:操作的类只能生成一个实例。
应用场景:网站的计数器,日志文件应用,数据库线程池等。
而在单例模式中,又分为饿汉单例模式懒汉单例模式。以下便通过代码展示出其区别。

饿汉单例模式

我们在通过Java获取一个对象时,一般是通过new调用类的构造函数生成,而当我们需要控制该类单例时,就需要将构造函数的访问权限设置为private以使得其他类无法通过构造方法创建实例,并给予一个类方法来获取Singleton类对象。

//代码块一
package com.singleton;

public class Singleton {
    //饿汉单例模式,在调用该类的第一时间就创建了对象
    private static Singleton instance = new Singleton();

    private Singleton() {
    }
    
    //定义一个类方法, 需要使用到Singleton实例时调用该方法获取
    public static Singleton getInstance() {
        return instance;
    }
}

这种静态初始化的方式是在自己被加载时就将自己实例化,所以被称之为饿汉单例类。

懒汉单例模式

其他类需要使用Singleton的类对象时,只能通过类方法getInstance()获取到Singleton对象。

//代码块二
package com.singleton;

public class Singleton {
    //懒汉单例:没有在调用该类的第一时间就创建一个对象, 而是在getInstance中根据条件创建
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        //只有当实例为空的时候才进行实例的创建
        if(instance == null)
            instance = new Singleton();
        return new Singleton();
    }
}

这种要在第一次被引用时,才会将自己实例化的类,称之为懒汉单例类。

但是代码块二 在多线程的情况下,无法保证只生成一个对象,因此需要再修改为以下代码来确保多线程下只有一个对象。

//代码块三
package com.singleton;

public class Singleton {
    //懒汉单例:没有在调用该类的第一时间就创建一个对象, 而是在getInstance中根据条件创建
    private static Singleton instance;

    private Singleton() {
    }
    //增加synchronized
    public synchronized static Singleton getInstance() {
        //只有当实例为空的时候才进行实例的创建
        if(instance == null)
            instance = new Singleton();
        return new Singleton();
    }
}

总结

由于饿汉单例模式是在类一加载的时候就生成实例,所以要提前占用系统资源;
懒汉单例模式又要面临着多线程访问的安全性问题,需要做到同步才可保证安全。

才疏学浅,如文中有错误,感谢大家指出。

原文地址:https://www.cnblogs.com/runningRookie/p/11108779.html