定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

结构和说明

创建型模式-单例模式 - 图1

示例代码

  1. public class SingletonDemo {
  2. /**
  3. * 枚举实现
  4. */
  5. public static enum SingletonEnum {
  6. /**
  7. * 单例对象
  8. */
  9. uniqueInstance;
  10. public static SingletonEnum getInstance() {
  11. return uniqueInstance;
  12. }
  13. public void singletonOperation() {
  14. }
  15. @Getter
  16. private String singletonData;
  17. }
  18. /**
  19. * 延迟加载内部类模式
  20. */
  21. public static class SingletonLazyHolder {
  22. private final static class SingletonHolder {
  23. private final static SingletonLazyHolder uniqueInstance = new SingletonLazyHolder();
  24. }
  25. private SingletonLazyHolder() {
  26. }
  27. public static SingletonLazyHolder getInstance() {
  28. return SingletonHolder.uniqueInstance;
  29. }
  30. public void singletonOperation() {
  31. }
  32. @Getter
  33. private String singletonData;
  34. }
  35. /**
  36. * 饿汉式
  37. */
  38. public static class SingletonHungry {
  39. private final static SingletonHungry uniqueInstance = new SingletonHungry();
  40. private SingletonHungry() {
  41. }
  42. public static SingletonHungry getInstance() {
  43. return uniqueInstance;
  44. }
  45. public void singletonOperation() {
  46. }
  47. @Getter
  48. private String singletonData;
  49. }
  50. /**
  51. * 懒汉式
  52. */
  53. public static class SingletonLazy {
  54. private static SingletonLazy uniqueInstance = null;
  55. private SingletonLazy() {
  56. }
  57. public static SingletonLazy getInstance() {
  58. if (uniqueInstance == null) {
  59. synchronized (SingletonLazy.class) {
  60. if (uniqueInstance == null) {
  61. uniqueInstance = new SingletonLazy();
  62. }
  63. }
  64. }
  65. return uniqueInstance;
  66. }
  67. public void singletonOperation() {
  68. }
  69. @Getter
  70. private String singletonData;
  71. }
  72. }

命名建议

一般建议单例模式的方法命名为 getInstance(), 这个方法的返回类型肯定是单例类的类型了。 getInstance() 方法可以有参数,这些参数可能是创建类实例所需要的参数,当然,大多数情况下是不需要的。

调用顺序

饿汉式

创建型模式-单例模式 - 图2

懒汉式

创建型模式-单例模式 - 图3

优缺点

  1. 时间和空间

比较上面两种写法: 懒汉式是典型的时间换空间 ,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。
饿汉式是典型的空间换时间 ,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,解决了运行时间。

  1. 线程安全

(1) 不加同步的懒汉式式线程不安全的
(2) 饿汉式是线程安全的

思考

本质

控制实例数目。

何时选用

当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式,这些功能恰好是单例模式要解决的问题。