`
zddava
  • 浏览: 243708 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

了解设计模式 之 创建模式(四) -- 单例模式

阅读更多
4. 单例模式(Singleton Pattern)

单例模式顾名思义,就是实现了单例,保证了在一个应用中只存在某个类的唯一实例。

单例模式包括3个变种:饿汉式,懒汉式和登记式。下边来一一的说明

(1) 饿汉式单例

public class EagerSingleton {
	
	// 单例
	private static final EagerSingleton instance = new EagerSingleton();

	private EagerSingleton() {
		// 构造函数设成private保证不能通过它去实例化
	}

	public static EagerSingleton getInstance() {
		return instance;
	}
}


此种方式在类被加载时就已经初始化了instance,所以称之为饿汉式。

但是,这种方式有个弱点,就是构造函数是私有的,也就是说这个类是无法继承的。

(2) 懒汉式单例

public class LazySingleton {
	private static LazySingleton instance = null;

	private LazySingleton() {
	}

	public synchronized static LazySingleton getInstance() {
		if (instance == null) {
			instance = new LazySingleton();
		}
		return instance;
	}
}


这个方式只在需要实例化的时候才去真正的实例化instance变量,在资源使用的效率上是比饿汉式要高的,但是它的构造函数同样是私有的,也无法继承此类。

另外,还有一个需要说明的地方,#getInstance()方法有很多人是推荐使用"双重检查锁定(DCL, double check locking)"这种方式去实现的,这样就不需要对整个方法来"synchronized"了,节省系统的开销。但是,由于Java的内存模型的原因,会导致"无序写入"问题,进而使DCL失效。但是,对于双重检查锁定,也是有补救的方法的,《Head First Design Pattern》中就提到了使用"volatile"关键字的方法,不过这个方法要在JDK1.5以上才生效,具体的代码如下:

public class LazySingleton {
	// 使用"volatile"
	private static volatile LazySingleton instance = null;

	private LazySingleton() {
	}
	
	// 使用DCL
	public static LazySingleton getInstance() {
		if (instance == null) {
			synchronized (LazySingleton.class) {
				if (instance == null) {
					instance = new LazySingleton();
				}
			}

		}
		return instance;
	}
}


(3) 登记式单例

登记式单例克服了饿汉式和懒汉式单例都无法继承的缺点,实现的代码如下所示:

public class RegisterSingleton {
	private static Map<String, RegisterSingleton> registry = new HashMap<String, RegisterSingleton>();
	static {
		RegisterSingleton x = new RegisterSingleton();
		registry.put(x.getClass().getName(), x);
	}

	protected RegisterSingleton() {
	}

	public static RegisterSingleton getInstance(String name) {
		if (name == null) {
			name = RegisterSingleton.class.getName();
		}
		if (registry.get(name) == null) {
			try {
				registry.put(name, (RegisterSingleton) Class.forName(name).newInstance());
			} catch (Exception e) {
				System.out.println("Error happened.");
			}
		}
		return registry.get(name);
	}
}


这样,RegisterSingleton的子类就可以实现单例了,代码如下:

public class SubRegisterSingleton extends RegisterSingleton {
	public SubRegisterSingleton() {
	}

	public static SubRegisterSingleton getInstance() {
		return (SubRegisterSingleton) RegisterSingleton.getInstance(SubRegisterSingleton.class.getName());
	}
}


这里,您可能会注意到,SubRegisterSingleton的构造函数是public的,因为在SubRegisterSingleton的父类RegisterSingleton需要实例化一个SubRegisterSingleton的对象,所以,这个构造函数必须是public的,但是,这里也会出现客户端直接使用这个构造函数去构造对象的问题,这个是登记式单例的一个弱点。另外,子类的单例实现是一定要父类来参与的,这个也有点浪费资源。
分享到:
评论

相关推荐

    java设计模式----单例模式

    在Java编程语言中,设计模式是一种经过验证的解决常见软件设计问题的最佳实践。单例模式是其中最常用的一种,它的核心思想是确保一个类只有一个实例,并提供全局访问点。单例模式的应用场景包括:控制资源的访问、...

    JAVA-设计模式-创建型模式-单例模式

    JAVA-设计模式-创建型模式-单例模式

    设计模式专题之(一)单例模式---设计模式单例模式模式示例代码(python--c++)

    单例模式是软件设计模式中的一种基础且广泛应用的模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在资源管理、配置对象、缓存等场景下非常常见,因为它可以避免因频繁创建和销毁对象而...

    单例模式---初学 优点--缺点

    单例模式是软件设计模式中的一种经典模式,主要用于限制类的实例化,确保在整个应用程序中,该类只有一个实例存在。这种模式在很多场景下都非常有用,例如管理共享资源、全局配置或者提供一个全局访问点等。 单例...

    设计模式单例模式和工厂模式综合应用

    "设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...

    设计模式-单例模式

    单例模式是一种广泛应用于软件设计中的创建型设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制共享资源的访问,比如线程安全的数据库连接池或者配置管理等。 在Java中...

    设计模式-单例设计模式

    5. **类间关系**:虽然在单例模式的类图中并不涉及其他类,但了解类之间的关系对于理解更复杂的设计模式非常重要。 #### 单例模式的构成要素 一个典型的单例模式包含以下关键要素: - **私有的构造方法**:防止外部...

    Java设计模式-单例模式详解

    Java设计模式-单例模式详解 单例模式是 Java 设计模式中的一种常用的设计模式,旨在保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式的目的是为了保证在一个进程中,某个类有且仅有一个实例。 ...

    设计模式之单例模式(结合工厂模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类只有一个实例存在,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于管理共享资源,如数据库连接池、线程池或者配置文件等。结合工厂模式,...

    一例读懂设计模式-单例模式、简单工厂模式.zip

    本资源“一例读懂设计模式-单例模式、简单工厂模式.zip”旨在帮助初学者通过实例深入理解这两种重要设计模式:单例模式和简单工厂模式。以下是关于这两个模式的详细讲解。 1. **单例模式**: 单例模式是一种限制类...

    ava常用设计模式-单例模式

    ava常用设计模式-单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,有以下特点: 1. 单例类只能有一个实例。 2. 单例类必须自己创建自己的唯一实例。 3. 单例类必须给所有其他对象提供这一...

    设计模式——单例模式

    **设计模式——单例模式** 在软件工程中,设计模式是一种在特定场景下解决常见问题的标准方案,可以被复用并提升代码质量。单例模式是设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式...

    设计模式 For iOS-02-单例模式

    总之,单例模式是iOS开发中常见的设计模式之一,它能够提供一种优雅的方式来管理和访问全局唯一的对象实例。无论是通过传统的非ARC方法,还是现代的ARC+GCD方式,实现单例模式都需要仔细考虑其线程安全性和生命周期...

    设计模式--单例模式java例子

    单例模式是软件设计模式中的一种经典模式,它在Java编程中被广泛使用。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于可以控制实例的数量,减少资源消耗,同时便于协调整个...

    23钟设计模式之单例模式

    单例模式是一种常用的设计模式,它的核心思想是在整个应用程序中,一个类只能有一个实例存在。单例模式常用于控制资源的共享,例如数据库连接池、日志服务等。单例模式有多种实现方式,常见的包括懒汉式、饿汉式以及...

    设计模式单例模式

    单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中需要频繁创建和销毁对象,且对象创建成本较高,或者需要共享资源的情况下非常...

    C#设计模式学习与演变过程-2-单例模式

    单例模式是软件设计模式中的一种经典模式,它旨在确保一个类只有一个实例,并提供一个全局访问点。在C#编程中,单例模式的应用广泛,特别是在需要频繁实例化然后销毁的对象,或者创建对象需要消耗大量资源的情况下,...

    常见设计模式-单例模式

    单例模式是设计模式中的一种,其主要目的是确保一个类只有一个实例,并且提供一个全局访问点来获取这个实例。在Java编程中,实现单例模式有多种方式,每种方式都有其优缺点。 1. **饿汉式**: 饿汉式在类加载时即...

    Qt单例设计模式(1-8)

    本系列教程将会逐步介绍如何创建和使用Qt单例模式,从基本的实现到更复杂的场景应用,帮助开发者掌握这一重要的设计模式,提高代码的复用性和可维护性。通过学习和实践,你将能够更好地理解和运用Qt中的单例设计模式...

Global site tag (gtag.js) - Google Analytics