前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Head First 设计模式之单例模式,每个人都是唯一

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

作者头像
用户4361942
发布2019-05-24 17:02:49
4530
发布2019-05-24 17:02:49
举报

单例模式

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

单例模式解决的问题

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

单例模式注意事项

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

使用场景

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

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

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

代码实现

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

//懒汉模式public class Singleton {    private Singleton() {    }
    private static Singleton instance = null;
    /* 静态工程方法,创建实例  缺点非线程安全*/    public static Singleton getInstance() {        if (instance == null) {            instance = new Singleton();        }        return instance;    }}
public class SingletonHungry {    //构造器私有化    private SingletonHungry(){}
    private static SingletonHungry instance = new SingletonHungry();
    /* 静态工程方法,创建实例*/    public static SingletonHungry getInstance() {        return instance;    }}

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

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

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

public class Singleton {    private Singleton() {    }
    private volatile static Singleton instance = null;
    public static Singleton getInstance() {        if (instance == null) {            synchronized (instance) {                if (instance == null) {                    instance = new Singleton();                }            }        }        return instance;    }
}

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

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

public enum Signleton {    INSTANCE;
    private Something something;
    Signleton() {        something = new Something();    }
    public Something getSomething() {        return something;    }}

优缺点

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

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

我的启发

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

设计模式系列历史:

Head First 设计模式之观察者模式,你我都是发布者和订阅者

Head first 设计模式之策略模式,来源于生活,用之于生活

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java程序员思维 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档