单例模式的实现方式

单例模式的实现方式:

静态变量/静态代码块方式

同步方法方式

双重验证方式

静态内部类方式


静态常量/静态代码块方式(不推荐)

优点:写法简单,不需要加锁,使用类加载的时候直接实例化,避免同步分问题
缺点:饿汉式(也就是非懒加载),如果程序运行的时候不需要使用到,那么就会导致内存浪费
public class Singleton{
	
	private static final Singleton INSTANCE = new Singleton();
	//私有构造器
	private Singleton(){
	}
	public static Singleton getInstance(){
		return INSTANCE;
	}
	//或者使用静态代码块的方式
	{
		INSTANCE = new Singleton();
	}
}


同步方法(不推荐)

优点:线程安全,保证了单例,懒加载(需要的时候创建)
缺点:性能太低,创建实例的只需要一次,其他的线程不应该再加锁而是可以直接return得到实例
public class Singleton{
	
	private static Singleton instance;
	//私有构造器
	private Singleton(){
	}
	//同步方法
	public static synchronized Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}	
	
}

双重验证方式(不是很推荐)

优点:懒加载,线程安全确保单例,其他的线程可以直接return获得到单例而不用获得锁——相对同步方法提高了点效率
缺点:同步加锁导致效率仍然不会太高
问题:里面的if(instance == null)有没有必要?
有必要!比如说现在有2个线程,都执行了外面的if(instance == null),然后其中一个线程获取到Singleton.class对象的锁,
然后执行instance = new Singleton()的操作,执行完之后释放锁,另外一个线程2这个时候申请到了锁,然后也执行了这个操作,
new了一个新的对象出来,那么就会导致非单例的出现!
public class Singleton{
	
	private static Singleton instance;
	//私有构造器
	private Singleton(){
	} 
	public static Singleton getInstance(){
		if(instance == null){
			synchronized(Singleton.class){
				if(instance == null){
					instance = new Singleton();
				}
			}
			return instance;
		}
	}
	
}


静态内部类方式(推荐!!!)

优点:保证单例,不需要加锁,懒加载(静态内部类并不会像类的静态方法一样,在初始化类的时候就被实例化创建,而是在需要的时候被创建);而且类的静态属性只会在第一次加载类的时候初始化,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的
public class Singleton{
	//私有构造器
	private Singleton(){
	}
	private static class Inner{
		private static final Singleton INSTANCE = new Singleton();
	}
	public static Singleton getInstance(){
		return Inner.INSTANCE;
	}
	
}

下面分析一些不能实现单例模式的例子

错误1:

优点: 懒加载
缺点:线程不安全,多线程下会产生多个实例
public class Singleton{
	private static Singleton instance;
	
	private Singleton(){
	}
	
	public static Singleton getInstance(){
		if( instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}


错误2:

优点:懒加载
缺点:未能保证单实例,因为如果有2个线程同时通过了if判断,然后就轮流获取Singleton.class锁,创建实例。
改进:改进后的就是双重验证——可以确保单实例
public class Singleton{
	private static Singleton instance;
	
	private Singleton(){
	}
	public static Singleton getInstance(){
		if(instance == null){
			synchronized(Singleton.class){
				instance = new Singleton();
			}
		}
		return instance;
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值