单例模式
设计模式中最简单的一种模式,即保证系统运行是,运行的类只有一个实例对象。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式注意事项:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
优点:
- 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
- 避免对资源的多重占用(比如写文件操作)。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
代码实例:
public class SingletonObject {//创建 SingletonObject 的对象private static SingletonObject instance = new SingletonObject ();//让构造函数为 private,这样该类就不会被实例化private SingletonObject (){}//获取唯一可用的对象public static SingletonObject getInstance(){return instance;}public void show(){System.out.println("这是一个单例模式的例子");}}public class SingletonPatternDemo {public static void main(String[] args) {//不合法的构造函数//编译时错误:构造函数 SingletonObject () 是不可见的//SingletonObject object = new SingletonObject ();//获取唯一可用的对象SingletonObject object = SingletonObject.getInstance();//调用方法object.show();}}
单例模式的几种实现方式
- 饿汉式
最上面的例子,也是最常用的方式,缺点在于会产生很多垃圾对象,消耗内存。
- 懒汉式 线程不安全
类中定义instance ,但是不实例化,等使用时在实例化,也就是所谓的懒加载。但是这种情况不适用于多线程,多线程的时候这就不是单例了,同时可能出现线程安全问题。
demo:public class Singleton {private static Singleton instance; // 先定义出instance,但是不实例化private Singleton (){}public static Singleton getInstance() {if (instance == null) {instance = new Singleton(); // 用到该类的时候才new出对象}return instance;}}
- 懒汉式 线程安全
和上面的模式相同只是在获取对象的时候用了synchronize关键字,保证线程安全
public class Singleton {private static Singleton instance;private Singleton (){}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
- 双检锁/双重校验锁
在懒汉式线程安全模式下,对事先定义的instance进行可见性操作,即加上volatile 关键字,保证,线程安全也保证对象可见,保证不会出现单例对象多例出现的情况
public class Singleton {private volatile static Singleton singleton;private Singleton (){}public static Singleton getSingleton() {if (singleton == null) {synchronized (Singleton.class) {if (singleton == null) {singleton = new Singleton();}}}return singleton;}}
- 枚举
个人常用的类型,多种筛选类型时使用直观明了
