单例模式

使用场景

只需要单个实例,比如说线程池、缓存等,如果存在两个不同的实例,就会引发种种问题。单例模式的设计就是为了保持永远只有一个实例。但是由于性能、存储上的考虑,单例模式有以下几种实现方式,可根据应用场景自行选择。

demo1 普通模式

public class Singleton {
    private static SingleTon uniqueInstance;

    private static Singleton getInstance() {
        uniqueInstance = new Singleton();
    }
}

demo2 延迟实例化模式

public class Singleton {
    private static SingleTon uniqueInstance;

    //添加synchronized防止两个线程同时进入到该方法
    //避免实例化过程进行两次
    private synchronized static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

demo3 急切实例化模式

public class Singleton {
    //保证线程安全,但是JVM在加载这个类时会马上创建实例
    //对性能会产生影响
    private static SingleTon uniqueInstance = new Singleton();

    private static Singleton getInstance() {
        return uniqueInstance;
    }
}

demo4 双重检查加锁

public class Singleton {
    //volatile确保变量被初始化后,多个线程能正确的处理该变量
    private volatile static SingleTon uniqueInstance;
    
    private static Singleton getInstance() {
        if (uniqueInstance == null) {
            //避免单例被初始化两次
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

关键点

  1. 私有的构造器
  2. 一个静态方法和一个静态变量

需要注意的点

  1. 在性能和资源的限制下选择最合适的方案

特定环境下的问题

  1. Java1.2之前, 单例没有全局引用时会被垃圾回收器回收, 1.2之后已经修复.
  2. 每个类加载器都定义了一个命名空间, 如果有多个类加载器, 就有可能会将一个类加载多次, 产生多个单例并存的情况. 解决办法: 自行指定类加载器, 并指定同一个类加载器.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容