【设计模式】之 单例模式

92 阅读2分钟

什么是单例模式

  1. 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,而且该类是提供一个取得其对象实例的方法
  2. 单例模式有两种方式:
    1. 饿汉式
    2. 懒汉式

示例代码

饿汉式示例代码

//有一个类, GirlFriend
//只能有一个女朋友
class GirlFriend {
​
    private String name;
​
    /**
     * public static int n1 = 100;
     * 为了能够在静态方法中,返回gf 对象,需要将其修饰为static對象,
     * 通常是重量級的對象, 餓漢式可能造成創建了對象,但是沒有使用.
     */
​
    private static GirlFriend gf = new GirlFriend("小红红");
​
    /**
     * 如何保障我们只能创建一个GirlFriend 对象
     * 步骤[单例模式-饿汉式]
     * 1. 将构造器私有化
     * 2. 在类的内部直接创建对象(该对象是static)
     * 3. 提供一个公共的static 方法,返回gf 对象
     */
    private GirlFriend(String name) {
        System.out.println("構造器被調用.");
        this.name = name;
    }
​
    public static GirlFriend getInstance() {
        return gf;
    }
​
    @Override
    public String toString() {
        return "GirlFriend{" + "name='" + name + ''' + '}';
    }
}

懒汉式示例代码

//希望在程序运行过程中,只能创建一個Cat 對象
//使用单例模式
class Cat {
​
    private String name;
​
    public static int n1 = 999;
​
    private static Cat cat; //默认是null
​
    /**
     * 步骤
     * 1.仍然构造器私有化
     * 2.定义一个static 静态属性对象
     * 3.提供一个public 的static 方法,可以返回一个Cat 对象
     * 4.懒汉式,只有当用戶使用getInstance 时,才返回cat 對象, 后面再次调用时,会返回上次创建的Cat 对象
     * 从而保存了实例
     */
    private Cat(String name) {
        System.out.println("构造器调用...");
        this.name = name;
    }
​
    public static Cat getInstance() {
        // 如果还没有创建对象
        if (cat == null) {
            cat = new Cat("小可爱");
        }
        return cat;
    }
​
    @Override
    public String toString() {
        return "GirlFriend{name='" + name + "'}";
    }
}

双重检测机制

public class SingletonDemo {
​
    private static volatile SingletonDemo instance = null;
    private SingletonDemo(){}
​
    /**
     * 双重检测机制
     */
    public static SingletonDemo getInstance(){
        if(instance==null){
            synchronized (SingletonDemo.class){
                if(instance==null){
                    instance=new SingletonDemo();
                }
            }
        }
        return instance;
    }
}

懒汉式和饿汉式的区别

  1. 创建对象时机不同
    • 饿汉式:在类加载时就创建了对象实例
    • 懒汉式:使用时才创建
  2. 线程安全
    • 饿汉式:线程安全
    • 懒汉式:线程不安全
  3. 资源浪费
    • 饿汉式:由于类加载时就进行了创建,可能存在实例化后没有使用的情况,造成资源浪费
    • 懒汉式:使用时创建,不存在资源浪费
  4. 在JavaSE标准类中,java.lang.Runtime就是经典的单例模式

参考

【零基础 快速学Java】韩顺平 零基础30天学会Java