1.定义
单例模式是对象的创建模式的一种,它保证一个类有且只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类则称为单例类。
2.使用场合
简而言之,就是任何只需要一个实例的地方.例如,窗口管理器,假脱机打印设备,数据库连接池。具体应用中,配置信息类,管理类,控制类,门面类,代理类通常被设计为单例类.
(1)配置信息类
负责配置文件的解析,通常被设计为单例类
(2)管理类
如连接池管理类,通常被设计为单例类
(3)控制类
如struts的ActionServlet类,也是单例类。
如下,只需在web.xml配置以下ActionServlet,tomcat容器自动装载后,即可完成对整个web系统提供ActionServlet实例。
Java代码
- action
- org.apache.struts.action.ActionServlet
- action
- *.do
(4)门面类
说到门面类,就不能不提门面(Facade)模式。客户端与多个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式。这个统一 的门面(Facade)对象就是门面类。在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。但这不是绝对的。
(5)代理类
在Jive中,使用代理模式实现权限访问的入口,就采用了单例模式。
3.单例模式在Java语言的实现
单例模式在Java语言的实现上有三种情况:饿汉式单例类,懒汉式单例类,登记式单例类。
(1)饿汉式单例类
饿汉式单例类饿汉式单例类是在Java 语言里实现得最为简便的单例类。在类被加载时,就会将自己实例化。
Java代码
- public class Singleton2{
- //注意这是private
- private static Singleton2 theInstance = new Singleton2();
- //这里提供了一个供外部访问本class的静态方法,可以直接访问
- public static Singleton2 getInstance(){
- return theInstance;
- }
- }
(2)懒汉式单例类
与饿汉式单例类不同的是,懒汉式单例类在第一次被引用时将自己实例化。
Java代码
- public class Singleton {
- public static Singleton theInstance = null;
- private Singleton(){}
- public synchronized static Singleton instance(){
- if(theInstance == null){
- return new Singleton();
- }
- return theInstance;
- }
- }
(3)登记式单例类
登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。
Java代码
- public class RegSingleton
- {
- static private HashMap m_registry = new HashMap();
- static
- {
- RegSingleton x = new RegSingleton();
- m_registry.put(x.getClass().getName(), x);
- }
- protected RegSingleton(){
- }
- static public RegSingleton getInstance(String name)
- {
- if (name == null)
- {
- name = "com.javapatterns.singleton.demos.RegSingleton";
- }
- if (m_registry.get(name) == null)
- {
- try
- {
- m_registry.put(name, Class.forName(name).newInstance());
- }
- catch (Exception e)
- {
- System.out.println("Error happened.");
- }
- }
- return (RegSingleton) (m_registry.get(name));
- }
- }
登记式单例类的子类
Java代码
- import java.util.HashMap;
- public class RegSingletonChild extends RegSingleton
- {
- public RegSingletonChild() {}
- static public RegSingletonChild getInstance()
- {
- return (RegSingletonChild)
- RegSingleton.getInstance(
- "com.javapatterns.singleton.demos.RegSingletonChild" );
- }
- public String about()
- {
- return "Hello, I am RegSingletonChild.";
- }
- }
一. 单例模式
整理自 《java与模式》阎宏编著
1.意图:
确保某个类只有一个实例,并且为该类提供一个全局的访问点。
2.类图:

3.原理:
a.将构造函数定义成私有使得不能通过构造函数来创建对象。
b.定义一个静态的方法提供公共接口,用于访问维一的实例。
4.特征:
a.单例类只能有一个实例.
b.单例类自己创建这个唯一的实例.
c.单例类必须给所有其他对象提供这个实例.
5.说明:
在EJB,JINI,RMI等分布式的java系统中使用单例模式时,尽量不要使用有状态(stateful)的。
6.使用案例:
一些资源管理器常常设计成单例模式,这些资源包括外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求 同时调用, 回收站等。 内部资源:譬如,系统配置文件管理器,日志管理器,系统记数管理部件,错误输出部件。
7.代码:
// Singleton.java
package singleton;
public class Singleton
{
private static Singleton instance;
/**
* 不允许通过构造字来实例化
*/
private Singleton()
{
}
/**
* 使用synchronized关键字,保障Singleton的线程安全
*/
public synchronized static Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}import java.util.HashMap; public class RegSingletonChild extends RegSingleton { public RegSingletonChild() {} static public RegSingletonChild getInstance() { return (RegSingletonChild) RegSingleton.getInstance( "com.javapatterns.singleton.demos.RegSingletonChild" ); } public String about() { return "Hello, I am RegSingletonChild."; } }