单例模式-阿里云开发者社区

开发者社区> 安全> 正文

单例模式

简介: 什么是单例模式?在一个项目中,单例模式确保某一个类只能有一个实例,这个类称为单例类。怎样确保某个类只能有一个实例,通常调用方法有两种方式: 创建类的一个对象,即new出一个对象,用该对象去调用类中方法; 使用类名直接调用类中方法,格式“类名.方法名()”想要类只有一个实例,必不能随意通过new出对象,禁止new对象就只能私有化构造方法,采用“类名.方法名()”这种方式获取方法。

什么是单例模式?在一个项目中,单例模式确保某一个类只能有一个实例,这个类称为单例类。
怎样确保某个类只能有一个实例,通常调用方法有两种方式:

  1. 创建类的一个对象,即new出一个对象,用该对象去调用类中方法;
  2. 使用类名直接调用类中方法,格式“类名.方法名()”
    想要类只有一个实例,必不能随意通过new出对象,禁止new对象就只能私有化构造方法,采用“类名.方法名()”这种方式获取方法。通过类名对用方法,此方法是属于类的方法,由于类的加载顺序限定,此方法必须是静态(static)的,且方法里的属性也必须是静态的。

单例核心三要素:

  1. 构造方法私有化
  2. 提供静态(static)的得到类对象的方法
  3. 类属性设为static

单例模式根据对象的创建时间不同,有分为EagerSingleton和LazySingleton。
EagerSingleton方法:

public class EagerSingleton {
    /** 静态方法访问静态成员变量*/
    private static EagerSingleton instance = new EagerSingleton();
    /** 私有构造方法,防止被实例化 */
    private EagerSingleton(){
    }
    /** 提供调用的方法 */
    public static EagerSingleton getInstance(){
        return instance;
    }
}

EagerSingleton方法缺点是该类加载的时候就会直接new 一个静态对象,当系统中单例类较多时,会使得启动速度变慢。
LazySingleton方法:

public class LazySingleton {
    //非线程安全
    private static LazySingleton instance = null;
    private LazySingleton(){
    }
    public static LazySingleton getInstance1(){
        if(instance == null){
            instance = new LazySingleton();
        }
        return instance;
    }
}

提供双重锁写法,保证线程安全:

public class DoubleCheckLock {

    private volatile static DoubleCheckLock instance = null;

    private DoubleCheckLock(){
    }

    public static DoubleCheckLock getInstance(){
        if(instance == null){
            synchronized (DoubleCheckLock.class) {
                if(instance == null)
                    instance = new DoubleCheckLock() ;
            }
        }
        return instance;
    }
}

“双重检查加锁”机制是当每次执行getInstance方法时先不同步,先检查instance是否存在,如果不存在才进行加锁,这是第一重检查;进入同步块synchronized 方法后,再次检查实例是否存在,如果不存在就创建实例instance,这是第二重检查。DoubleCheckLock 机制使用关键字volatile,被volatile修饰的变量值不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的操作该变量。

参考:
1.https://www.cnblogs.com/java-my-life/archive/2012/03/31/2425631.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
+ 订阅

云安全开发者的大本营

其他文章