首页
学习
活动
专区
工具
TVP
发布

Head First 设计模式之单例模式,每个人都是唯一

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

单例模式解决的问题

保证一个类仅有一个实例,并提供一个访问它的全局访问点。防止一个全局使用的类频繁地创建与销毁,节省资源,方便管理。

单例模式注意事项

单例类只能有一个实例。单例类必须自己创建自己的唯一实例,其他任何地方无法通过构造方法创建对象,也意味着需要构造方法私有化。单例类必须给所有其他对象提供这一实例。

使用场景

网站的计数器,一般也是采用单例模式实现,否则难以同步。

数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。

操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

代码实现

单例模式又分为懒汉模式和饿汉模式,两种的区别在于是不是启动的时候创建对象,饿汉模式不管是否需要对象,都先创建好。懒汉模式是在需要对象的时候,进行对象的创建。本质区别是时间和空间的取舍,懒汉模式是用时间换空间,启动时候不需要创建对象,节省了空间,但是访问对象的时候要判断是否已经创建对象,会浪费一些时间。饿汉模式是用空间换时间,启动的时候创建对象,浪费了一些空间,但是访问的时候,不需要创建对象和判断对象是否存在,节省了时间,提高了效率。

上面的懒汉模式存在一些问题,在多线程的情况下,多个线程同时调用getInstance方法,可能会创建多个对象,违背了单例模式只有一个实例的原则,需要对getInstance进行同步处理。

虽然上面的代码可以保证只会创建一个单例,但是效率很低,是对整个getInstance方法加锁,一旦对象已经创建,每次只能有一个线程访问对象,可以通过双检锁的方式进行优化,既可以保证只会创建一个对象,同时又允许多个线程访问实例。

使用volatile修饰instance属性,保证属性的可见性,只要发生变化对所有线程可见,因为同步代码范围变小,可以提高效率。双检锁可以保证只会创建一个对象实例。

保证单例,还有很多方式,枚举自身是线程安全的,也是一种不错的选择。

优缺点

优点:在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。由于在系统内存中只存在一个对象,因此可以 节约系统资源,当需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。

缺点:不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 单例类的职责过重,在一定程度上违背了“单一职责原则”。

我的启发

世界上没有两片完全相同的树叶,人何尝不是如此,每个人都是唯一,做最真实的自我。我是幸运的,因为我还活着,珍爱生命,过好每一天。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190430A02QCC00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券