为了账号安全,请及时绑定邮箱和手机立即绑定

单例模式

单例模式

定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例(以静态方法)

应用

  • 整个项目中需要一个共享访问点或者共享数据
  • 创建一个对象需要消耗的资源过多,如要访问IO和数据库资源等
  • 需要定义大量静态常量和静态方法的环境

优点

  • <font color=#2a3342>减少内存开支</font>
    在内存中只有一个实例,减少对象频繁创建和销毁的性能开销
  • <font color=#2a3342>避免对资源多重占用</font>
    由于只有一个实例存在,避免对同一资源文件的同时操作

单例模式<font color=#3480d7>6</font>种实现

1. 饿汉模式

public class Singleton {
    // 第一次加载到内存中就会被初始化,不管需不需要都给一个实例
    // 所以创建实例本身是线程安全的
    private static final Singleton instance = new Singleton();
    // 构造函数
    private Singleton() {
    }
    // 静态方法获取实例
    public static Singleton getInstance() {
        return instance;
    }
}

2. 懒汉模式

public class Singleton {
    // 一开始不新建实例,需要时再创建
    private static Singleton instance = null;

    private Singleton() {
    }
    // 线程不安全,多个线程调用该方法时还有可能产生多个实例
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

3. 线程安全的懒汉模式

public class Singleton {
    private static Singleton instance = null;

    private Singleton() {
    }

    // 添加关键字synchronized
    // 同一时刻最多只有一个线程调用该方法,结果效率不是很好
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

4. 双重检验锁

public class Singleton {
    // JDK1.5或之后版本添加关键字volatile,防止编译器自行优化代码
    private /**volatile**/ static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        // 第一重检验锁,如果不为空直接返回实例
        if (instance == null) {
            synchronized (Singleton.class) {
                // 第二重检验锁,因为可能有多个线程进入
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

5. 静态内部类

public class Singleton {
    // 线程安全,饿汉式静态内部类
    // 就算Singleton类被装载了,instance不一定被初始化,因为Inner类没有被主动使用
    private static class SingletonInner {
        private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton() {

    }

    public static Singleton getInstance() {
        return SingletonInner.INSTANCE;
    }
}

6. 枚举

/**
 * 通过Singleton.INSTANCE来访问实例对象
 * 而且创建枚举默认就是线程安全的,还可以防止反序列化带来的问题
 */
public enum Singleton{
    // 实际上做了
    /**new Enum<Singleton>("INSTANCE", 0)**/
    INSTANCE;
    // 其他方法
}
点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消