Java线程安全的单例模式

前言

很多人比较熟悉单例模式,而且单例涉及的知识也不少,如果采用同步锁判断实现单例,有如下几点:

  • 利用私有访问控制符设置构造函数Constructor,从而禁止通过new创建对象实例。
  • 静态成员的类加载过程
  • 懒汉模式和饿汉模式
  • 多线程的同步锁synchronized效率优化问题
  • volatile关键词所涉及的JVM工作内存与主内存的同步问题。
  • 序列化和反序列化通过反射创建新的实例对象并返回的问题,以及通过重载readResolve()方法避免返回新实例的方法。

** 如果采用静态内部类只会被加载一次的特性来实现单例模式的话,还需要使用一下知识:**

  • 静态内部类与静态成员和静态方法有所不同,静态内部类是在被访问的时候会被有且只有加载一次。
  • 静态内部类的加载是由类加载器加载并初始化的,而类加载方法loadClass利用了synchronized 实现同步锁,所以是线程安全的。

** 如果利用枚举来实现当例 **

  • 利用枚举的线程安全
  • 枚举在序列化和反序列化时不受反射影响
  • 枚举实现单例缺点:需要花费至少两倍以上的内存空间,不适合android使用

下面展示单例代码

# 同步锁判断实现单例
public class Singleton {
    private static volatile Singleton singleton = null;
 
    private Singleton(){}
 
    public static Singleton getSingleton(){
        if(singleton == null){
            synchronized (Singleton.class){
                if(singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }    
  #  避免序列化和反序列化破坏单例模式
   private Object readResolve() {
        return singleton;
    }
}

缺点: 读取效率差,代码相对复杂

# 静态内部类实现单例
public class Singleton {
    private static class Holder {
        # 存放在静态内部类里面的单例引用
        private static Singleton singleton = new Singleton();
    }

    private Singleton(){}

    # 获取单例对象的方法
    public static Singleton getSingleton(){
        return Holder.singleton;
    }
}

缺点: 会被序列化和反序列化破坏单例结构

# 枚举法实现单例
public enum Singleton {
    INSTANCE;
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}

缺点:需要花费至少两倍以上内存,不适合移动端使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 单例模式作为一种常见的设计模式,在程序中非常常见,主要是为了保证一个类只有一个唯一的对象。 从简单的“饿汉式”、“...
    Android_大船阅读 4,162评论 0 12
  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 4,507评论 4 34
  • 在Java中,单例模式分为很多种,本人所了解的单例模式有以下几种,如有不全还请大家留言指点: 饿汉式 懒汉式/Do...
    Duang了个Duang阅读 1,813评论 0 2
  • 在看微信支付的SDK时,看到里面有一个单例模式实现采用了内部类的方式,于是查了一下,发现这是一种线程安全的单例实现...
    Peter520阅读 996评论 0 1
  • 在人群中穿梭看着身边的行人匆匆而过,不知为何就觉得每个人都带着自己的故事,也许欢乐也许哀愁,可能美好可能悲哀,或许...
    诺诺1013阅读 286评论 0 0

友情链接更多精彩内容