设计模式笔记_五_单件模式

[TOC]

引言

为什么要用单件模式?

  • 有一些对象只需要一个实例。比如:线程池、缓存、对话框等。

为什么不可以用全局变量解决?

  • 如果使用全局变量,那么必须在程序一开始就创建对象(JVM可能在使用时才创建)。如果在程序一次执行中没有用到,会浪费资源。

为什么不能创建一个类,把所有方法和变量都定义为静态,把类直接当做一个单件?

  • 静态变量初始化的控制权在Java手上,这么做可能导致混乱和不易察觉的bug。使用对象的单件,比较保险。

单件模式

定义

单件模式 确保一个类只有一个实例,并提供一个全局访问点。

经典的单间模式实现

类图

多线程带来的问题

处理多线程

getInstance()变成同步(synchronized)方法:

改善多线程

同步对运行效率影响很大,实际上,只有第一次执行时才需要同步。

使用”急切“创建实例

如果应用程序总是创建并使用单件实例,或者在创建和运行时方面的负担不太繁重,你可能需要急切(eagerly)创建次单件,而不用延迟实例化的做法:

使用双重检查加锁

使用双重检查加锁(double-checked locking),在getInstance()中减少使用同步。

利用双重检查加锁,首先检查是否实例已经创建了,如果未创建,才进行同步。

总结

  • 单件模式确保程序中一个类最多只有一个实例

  • 单价模式也提供访问这个实例的全局点

  • 在Java中实现单件模式需要私有构造器、一个静态方法、一个静态变量

  • 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题

  • 小心,如果使用多个类加载器,可能导致单件失效而产生多个实例

其他问题

多个类加载器

两个类加载器可能有机会各自创建自己的单件实例,导致同一个类会被加载多次,就会出现产生多个单件并存的怪异现象。

解决办法:自定制定类加载器,并指定用一个类加载器。

最后更新于

这有帮助吗?