设计模式学习笔记单例模式

9次阅读

共计 1780 个字符,预计需要花费 5 分钟才能阅读完成。

一、概念

一般采用单例模式就是为了满足“只创建一个类”的需要。

单例模式 有两个特点:
(1)一个类仅有一个实例
(2)仅有一个全局访问点

二、写法

1、饿汉式
所谓饿汉式,是指这个类的实例在类加载阶段就已经创建出来了。

public class Singleton1 {
    // 在类的内部实例化一个实例
    private static final Singleton1 instance = new Singleton1();
    // 隐藏构造方法
    private Singleton1() {}
    // 对外开放一个获取实例的方法
    public static  Singleton1 getInstance(){return instance;}
}

当然也可以使用 static 代码块。(注意这里的 final,看网上有各种写法,加或者不加的都有,我认为这里可以加,这样 getInstance 方法里就不需要判空了)

这种方式虽然能够有效避免线程安全的问题,但是却可能造成不必要的浪费,因为也许这个实例并不需要用到,或者就用到一两次,却要一直占用内存。

2、静态内部类

public class InnerClassSingleton {
    // 在静态内部类中实例化对象
    private static class SingletonHolder{private static final InnerClassSingleton instance = new InnerClassSingleton();
    }
    // 隐藏构造方法
    private InnerClassSingleton(){}
    // 对外提供访问方法
    public static final InnerClassSingleton getInstance() {return SingletonHolder.instance;}
}

3、懒汉式
所谓懒汉式,就是在使用时才加载,比较“懒一些”。

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){}
    public static Singleton2 getInstance(){
        // 在对象被使用时才实例化
        if (instance == null)
            instance = new Singleton2();
        return instance;
    }
}

注意:加上 synchronized 关键字就可以保证线程安全。

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){}
    public static synchronized Singleton2 getInstance(){
        // 在对象被使用时才实例化
        if (instance == null)
            instance = new Singleton2();
        return instance;
    }
}

4、当然上述方式效率比较低,因为 synchronized 锁的范围太大了

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){}
    public static Singleton2 getInstance(){
        // 在对象被使用时才实例化
        synchronized (Singleton2.class){if (instance == null)
                instance = new Singleton2();
            return instance;
        }
    }
}

这样就缩小了锁的范围,但是这种方式依然存在问题,因为 Java 内存模型的机制,程序可能会崩溃,因此就要用到 volatile。

5、使用 volatile

public class Singleton2 {
    private static volatile Singleton2 instance;
    private Singleton2(){}
    public static Singleton2 getInstance(){
        // 在对象被使用时才实例化
        if (instance == null){synchronized (Singleton2.class){if (instance == null)
                    instance = new Singleton2();
                return instance;
            }
        }
    }
}

6、枚举式

public enum  Singleton3 {
    INSTANCE;
    Singleton() {}
}

正文完
 0