前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从单例模式说起

从单例模式说起

作者头像
春哥大魔王
发布2018-07-23 11:33:39
3430
发布2018-07-23 11:33:39
举报
文章被收录于专栏:服务端技术杂谈

单例模式是我们比较常用的设计模式,玩好单例模式也会涉及到很多java基础知识。 单例作为全局性实例,在多线程情况下全局共享的变量会变得非常危险。

双重检测:

双重检测是比较常用的一种实现方式:

代码语言:javascript
复制
public class Singleton {    public static final volatile Singleton singleton = null;    private Singleton(){}    public static Singleton getInstance(){        if(singleton == null){ 
           synchronize (Singleton.class){               if( singleton == null ) { 
                   singleton = new Singleton();
               }
        }        return singleton;
    }
}

如果不用volatile修饰,多线程执行到 singleton == null 时,多个实例会被创建出来,就可能造成内存泄露问题。

当然你可以说可以用互斥同步的方式进行,但是我们做了同步,多线程的操作就变成了串型了,效率会很低,因为创建对象其实只需要一次,但是后面的读取都需要同步了。

还有一个原因,在jvm编译器可能会对指令进行重拍和优化,就是判断singleton == null的判断顺序可能无法保证。 于是我们将变量用volatile修饰,这个变量就不会在多线程中存在副本,都必须从主内存读取,同时避免了指令重拍。

当两个线程执行完第一个 singleton == null 后等待锁, 其中一个线程获得锁并进入synchronize后,实例化了,然后退出释放锁,另外一个线程获得锁,进入又想实例化,会判断是否进行实例化了,如果存在,就不进行实例化了。

静态内部类(懒汉模式)

一个延迟实例化的内部类的单例模式,一个内部类的容器,调用getInstance时,JVM加载这个类

代码语言:javascript
复制
public final class Singleton {    private static class SingletonHolder {        static final Singleton INSTANCE =  new Singleton();
    } 
    private Singleton() {}    public static final Singleton getInstance() {        return SingletonHolder.INSTANCE;
    }
 }

由于SingleHolder是私有的,除了getInstance()之外没有方法可以访问它,只有在getInstance()被调用时才会真正创建,

首先,其他类在引用这个Singleton的类时,只是新建了一个引用,并没有开辟一个的堆空间存放(对象所在的内存空间)。 接着,当使用Singleton.getInstance()方法后,Java虚拟机(JVM)会加载SingletonHolder.class(JLS规定每个class对象只能被初始化一次),并实例化一个Singleton对象。

缺点:

需要在Java的另外一个内存空间(Java PermGen 永久代内存,这块内存是虚拟机加载class文件存放的位置)占用一个大块的空间。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 春哥talk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 双重检测:
  • 静态内部类(懒汉模式)
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档