• Java设计模式--单例模式


    直想写点关于设计模式的东西,却懒到现在都没写过什么,今天上午看到项目中的代码,就在这个中午抽出时间写点东西,抛个项目截图先:

     

    单例模式:

    单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

    下面介绍Java中常用的单例模式:

    一、懒汉模式

     

    这种写法看上去似乎实现了单例模式,然鹅、实际应用中却不实用,尽管我所在的项目中有着类似的代码,我也不得不说确实如此;

    优点:实现了按需创建,即懒加载

    缺点:线程不安全。在多线程案例中,这种方式并没有完全实现单例模式。例如当多个线程访问getSingleton方法时,一起判断null == singleton,这时就会创建多个Singleton的实例。

    实现了线程安全的懒汉模式(两种方式写法不同,却是一致的):

    上面两种写法虽有差异,但运行效果却是相同的;

    优点:解决了多线程的安全问题

    缺点:效率却低的不要不要的。因为每当有线程访问时,就会出现线程排队等候,真正去创建实例的线程只有一个。

    现实中也有人通过添加volatile关键字对对象实例进行限制,volatile保证其对所有线程的可见性,并且禁止对其进行指令重排序优化。

     下面介绍下兼顾线程安全与效率的懒汉模式:

    这种方式被称为双重检查锁/双重校验锁方式,通过两次判null操作,它解决了线程安全的问题,不会创建多个实例。同时、也提高了线程访问的效率问题。这种方式可以算作是懒汉模式的最优解,但并非单例模式的最优解。

    二、饿汉模式

     

    优点:写法简单,一目了然

    缺点:无法做到按需创建,即懒加载,增加负载。

    注意:这里的增加负载要看具体情况,就上面的代码而言,new一个Singleton实例,算不上增加负载,但如果你new的是一个很大的对象,这时你应该考虑这个问题了。

    三、静态内部类

    把Singleton实例放到一个静态内部类中,这样就避免了静态实例在Singleton类加载的时候就创建对象,并且由于静态内部类只会被加载一次,所以这种写法也是线程安全的。

    优点:线程安全,按需创建。

    缺点:1、需要额外的工作(Serializable、transient、readResolve())来实现序列化,否则每次反序列化一个序列化的对象实例时都会创建一个新的实例。

       2、可能会有人使用反射强行调用我们的私有构造器(如果要避免这种情况,可以修改构造器,让它在创建第二个实例的时候抛异常)。

    四、枚举

    使用枚举除了线程安全和防止反射强行调用构造器之外,还提供了自动序列化机制,防止反序列化的时候创建新的对象。因此,Effective Java推荐尽可能地使用枚举来实现单例。

    最后,不管采取何种方案,请时刻牢记单例的三大要点:

    • 线程安全
    • 延迟加载
    • 序列化与反序列化安全
  • 相关阅读:
    [Form Builder]POST 与 commit_form 的区别
    [Form Builder]Form中的validate验证事件
    [Form Builder]Oracle Form系统变量中文版总结大全
    [Form Builder]NAME_IN()与COPY()
    [Form Builder]APP_ITEM_PROPERTY.SET_PROPERTY 用法
    解决MVC模式文件下载附件中文名称乱码
    [ASP.NET MVC]笔记(四) UnobtruSive AJAX和客户端验证
    log4net的使用
    Linq 实现sql中的not in和in条件查询
    [ASP.NET MVC]笔记(三) 成员资格、授权和安全性
  • 原文地址:https://www.cnblogs.com/itachy/p/8287564.html
Copyright © 2020-2023  润新知