1.单例模式

定义

单例模式(Singleton Pattern)使我们平时较为常用与简单的模式
定义:确保一个类只产生了一个实例,并且自行实例化,向整个系统提供这个实例

通用源码

//饿汉式
public class Singleton {
	private static final Singleton singleton = new Singleton();
	//限制类产生多个对象不能new
	private Singleton() {
	}
	//只能通过这个方法来获得实例对象
	public static Singleton getSingleton() {
		return singleton;
	}
	//类中其他方法都尽量使用static
	public static void doSomething() {
	}
}

//懒汉式
public class Singleton {
	private static final Singleton singleton = null;
	//限制类产生多个对象不能new
	private Singleton() {
	}
	//只能通过这个方法来获得实例对象
	public static Singleton getSingleton() {
		if(singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}
	//类中其他方法都尽量使用static
	public static void doSomething() {
	}
}

通用源码如上图所示,Singleton类称为单例类,通过使用private关键字修饰的构造函数确保了在整个系统中不能通过new来产生实例,只能在Singleton中其自己使用new Singleton(),这样一个系统中也就只产生一个实例,且是自行实例化

应用

优点

  1. 单例模式在内存中只会存在一个实例,减少了内存开支,特别如果是一个要频繁创建、销毁的类,而创建、销毁时性能又无法优化,单例模式的效果就十分明显
  2. 单例模式只产生一个实例,就减小了系统的性能开销,当一个对象产生需要比较多的资源,如读取配置文件时,就可以通过在应用启动时直接产生一个单例对象,再永久驻留内存中的方式来解决
  3. 单例模式可以避免对资源的多重占用
  4. 单例模式可以在系统设置全局访问点,优化、共享资源访问

缺点

  1. 单例模式一般没有接口,扩展起来就比较困难,若要扩展只能进行修改代码
  2. 单例模式对于测试不方便
  3. 单例模式与单一职责原则有所冲突

使用场景

  1. 要求生成唯一序列号的场景
  2. 在整个项目中需要一个共享访问点或有共享数据时
  3. 创建一个实例需要消耗的资源过多(如要访问数据库、IO流)
  4. 需要定义大量的静态常量和静态方法的情况,可以使用单例模式(如工具类,也可以直接用static)

注意事项

使用单例模式时,要注意在高并发情况下的线程同步问题
在通用源码的示例代码中,可以看到单例模式的写法分为两种:饿汉式和懒汉式
饿汉式不需要担心而懒汉式就需要注意线程同步问题,懒汉式在获得实例对象时,需要先判断,这就会又一种情况发生:如果一个线程A执行到singleton = new singleton(),但由于对象初始化需要时间,所以还没有获得对象,而这时另一个线程B也正在执行,并执行到if(singleton == null)的判断,那这样线程B判断为真,于是进行下去,这样的话,线程A/B都获得了实例,内存中也就会产生多个实力

解决线程不安全的方法:在getSingleton方法前加synchronized关键字,但是这样也会影响性能,所以还是建议去使用饿汉式

总结

单例模式是较为简单的一种模式,也是使用较为广泛的一种模式,最熟知的比如在Spring中,每个Bean默认都是单例的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值