单例模式介绍

单例模式,是为了确保在整个软件体统中,某个类对象只有一个实例,并且该类通常会提供一个对外获取该实例的public方法(静态方法)。
比如日志、数据库连接池等对象,通常需要且只需要一个实例对象,这就会使用单例模式。

单例模式的八种模式

  • 饿汉式(静态常量)
  • 饿汉式(静态代码块)
  • 懒汉式(线程不安全)
  • 懒汉式(同步方法)
  • 懒汉式(同步代码块)
  • 懒汉式(双重检查)
  • 静态内部类
  • 枚举

下面依次来说明一下:

饿汉式(静态常量)

通常,我们创建一个对象的方式就是new,但是,当我们考虑只创建一个实例的时候,就应该禁止外部来通过new的方式进行创建。同时,由于无法使用new,你应该考虑提供一个获取单例对象的方式给别人。

思路

1.将构造器私有化(防止外部new,但是对反射还是有局限)
2.类的内部创建对象
3.对外提供一个获取实例静态的public方法

代码实现如下:

public class Singleton1 {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
        HungrySingleton hungrySingleton1 = HungrySingleton.getInstance();
        System.out.println(hungrySingleton == hungrySingleton1);
    }
}

class HungrySingleton {
    //1.私有化构造器
    private HungrySingleton() {
    }

    // 2.类内部创建对象,因为步骤3是static的,
    // 该方法也是static的
    private static HungrySingleton instance = new HungrySingleton();

    //3.对外提供一个获取对象的方法,
    // 因为调用方式的目的就是为了获取对象,
    // 所以该方法应该是static的。
    public static HungrySingleton getInstance() {
        return instance;
    }
}

运行程序显示,我们的确只创建了一个对象实例。

小结

优点:代码实现比较简单,在类加载的时候就完成了实例化,同时,该方式能够避免线程安全问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
这种方式基于classloder机制避免了多线程的同步问题,不过, instance在类装载时就实例化,在单例模式中大多数都是调用getInstance方法, 但是导致类装载的原因有很多种, 因此不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance就没有达到lazy loading的效果。

最新文章

  1. JavaScript学习笔记5 之 计时器 & scroll、offset、client系列属性 & 图片无缝滚动
  2. 设计模式--代理模式Proxy(结构型)
  3. 显示转换explicit和隐式转换implicit
  4. 《图形学》实验七:中点Bresenham算法画椭圆
  5. kendo-ui学习笔记——题记
  6. 数据获取以及处理Beta版本展示
  7. Android--TextView 文字显示和修改
  8. HDU 2094 产生冠军(半拓扑排序+map)
  9. Tutorial: WPF User Control for AX2012
  10. HTML--8Window.document对象
  11. hdoj 2112 HDU Today
  12. Jquery获得控件值的方法
  13. 01标题背包水章 HDU2955——Robberies
  14. MIT6.828 虚拟地址转化为物理地址——二级分页
  15. Lua,Lua API,配置文件
  16. EasyUI Combobox 默认设置
  17. 浅谈odoo 后台与前端文件(附件)的存储与下载
  18. Fontawesome字体使用说明及其常用效果语法
  19. 跟我学ASP.NET MVC之二:第一个ASP.NET MVC程序
  20. 转-->>mysql的bin log

热门文章

  1. spring源码深度解析— IOC 之 循环依赖处理
  2. Spring 注解编程之注解属性别名与覆盖
  3. Akka-CQRS(16)- gRPC用JWT进行权限管理
  4. C++学习书籍推荐《Effective STL(英文)》下载
  5. Unix及Linux编辑器vi/vim基本使用方法
  6. Java平台调用Python平台已有算法(附源码及解析)
  7. Junit初级应用实例
  8. [原创]实现MongoDB数据库审计SQL语句的脚本
  9. html css 布局小细节
  10. getlasterror() 输出错误信息,