单例(Singleton)设计模式

475 阅读2分钟

单例(Singleton)设计模式

单例就是在程序的运行过程中,一个类只有一个实例的存在

饿汉式单例

线程安全的

public class Singleton {
    //(1) 构造方法私有化
    private Singleton() {};
    //(2) 提供一个静态的私有的本类对象
    //在Singleton类加载内存时给静态变量obj分配存储空间并初始化
    private static Singleton obj = new Singleton();
    //(3) 提供一个公共的方法返回这个类对象
    public static Singleton getInstense() {
        return obj;
    }
}

线程不安全懒汉式单例

public class Singleton {
    //(1) 构造方法私有化
    private Singleton() {};
    //(2) 提供一个静态的私有的本类对象,但不赋值
    private static Singleton obj;

    //(3) 提供一个公共的方法返回这个类对象
    public static Singleton getInstense() {
        //在第一次调用的时候对obj进行赋值
        if (obj == null) {
            obj = new Singleton();
        }
        return obj;
    }
}

线程安全的懒汉式单例

给上述方法方法简单的加锁,便可使其变成线程安全的:

public class Singleton {
    //(1) 构造方法私有化
    private Singleton() {};
    //(2) 提供一个静态的私有的本类对象,但不赋值
    private static Singleton obj;

    //(3) 提供一个公共的方法返回这个类对象
    public synchronized static Singleton getInstense() {
        //在第一次调用的时候对obj进行赋值
        if (obj == null) {
            obj = new Singleton();
        }
        return obj;
    }
}

但是,多线程时,只在第一次访问并创建对象时,可能出现线程安全问题,而创建完之后,就没必要再使用锁了,故效率低下 解决思足路:将同步代码块的范围缩小

public class Singleton {
    //(1) 构造方法私有化
    private Singleton() {}
    
    //(2) 提供一个静态的私有的本类对象,但不赋值
    private static Singleton obj;

    //(3) 提供一个公共的方法返回这个类对象
    public static Singleton getInstense() {
        //在第一次调用的时候对obj进行赋值
        if (obj == null) {
            synchronized (Singleton.class) {
                if (obj == null) {
                    obj = new Singleton();
                }
            }
        }
        return obj;
    }
}

应用场景

  • 在应用场景中,某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
  • 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。
  • 当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。

视频讲解

[video(video-sIeGFmvC-1574932453067)(type-bilibili)(url-player.bilibili.com/player.html…)]