设计模式之单例模式使用心得

说起设计模式,已经老生常谈了,我在这里,仅记录下自己的认识,同时也方便他人。

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

必要性:当一个对象被使用的频率较高,为避免频繁创建、销毁对象,更高效的使用内存。

作用:

  •  用来保证这个类在运行期间只会被创建一个类实例;
  •  提供了一个全局唯一访问这个类实例的访问点。

作用域:Java里面实现的单例是一个虚拟机的范围。

 

两种构造方式:

饿汉式:

private static Singleton Instance = new Singleton();

时间换空间,饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的。  

懒汉式:

private static Singleton Instance = null;

空间换时间,不加同步的懒汉式是线程不安全的。比如,有两个线程,一个是线程A,一个是线程B,它们同时调用getInstance方法,就可能导致并发问题。

那么懒汉式如何实现线程安全? synchronized关键字

public static synchronized Singleton getInstance(){}

但这样会降低整个访问的速度,而且每次都要判断。可以用双重检查加锁。

双重加锁机制:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例。这是第二重检查。

双重加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

/**
     * 双重检查加锁的单例模式
     */
    public class Singleton {
        /**
         * 对保存实例的变量添加volitile的修饰
         */
        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;
    }

一种更好的单例实现方式:静态内部类(类加载机制保证线程安全)

 

 

public class Singleton {

	/**
	 * 类级的内部类,也就是静态类的成员式内部类,该内部类的实例与外部类的实例
	 * 没有绑定关系,而且只有被调用时才会装载,从而实现了延迟加载
	 *
	 */
	private static class SingletonHolder{
		/**
		 * 静态初始化器,由JVM来保证线程安全
		 */
		private static final Singleton instance = new Singleton();
	}
	
	/**
	 * 私有化构造方法
	 */
	private Singleton(){
		
	}
	
	public static Singleton getInstance(){
		return SingletonHolder.instance;
	}
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值