单例模式是一个简单的创建者类型的模式,必须保证在系统中最多只能有一个唯一的对象实例,有如下特点:
1、单例类必须保证最多只有一个实例;
2、必须由单例类自己创建唯一的实例;
3、单例类必须给其他所有对象提供其唯一的实例。
根据创建时间,单例模式又可以分为饥汉式和饱汉式两种,下面通过JAVA代码来分析二者的优缺点。
饥汉式单例模式:
/**
* HungerySingletonPatternTest
* 饥汉式单例模式
*/
public class HungerySingletonPatternTest{
private static final HungerySingletonPatternTest instance = new HungerySingletonPatternTest();
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private HungerySingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static HungerySingletonPatternTest getInstance(){
return instance;
}
}
饥汉式单例模式优点是简单切线程安全,但是缺点也很明显,在类加载时就要初始化单例类的对象,有可能在整个系统的生命周期内都用不到该单例对象,这样就造成了浪费,特别是该单例类的生成和持有要占很大资源的时候。
饱汉式单例模式改掉了饥汉式单例模式的缺点,代码如下:
/**
* FullSingletonPattern
* 饱汉式单例模式
*/
public class FullSingletonPatternTest{
private static final FullSingletonPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private FullSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static synchronized FullSingletonPatternTest getInstance(){
if(instance == null){
new HungerySingletonPatternTest();
}
return instance;
}
}
饱汉式单例模式虽然改进了饥汉式单例模式的缺点,但是每次在获取单例对象时都要锁(Class Lock),在单线程或没够对单例类对象有竞争的应用场景下,加锁会造成不必要的性能损失。
对于饱汉式单例模式的缺点,有人提出了所谓的“双重检查锁”的饱汉式单例模式,代码如下:
/**
* DoubleCheckerSingletonPatternTest
* “双重检查锁”饱汉式单例模式
*/
public class DoubleCheckerSingletonPatternTest{
private static final DoubleCheckerPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private DoubleCheckerSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static DoubleCheckerSingletonPatternTest getInstance(){
if(instance == null){
synchronized(DoubleCheckerSingletonPatternTest.class){
if(instance == null){
new DoubleCheckerSingletonPatternTest();
}
}
}
return instance;
}
}
但是“双重检查锁”的饱汉式单例模式,实际上不是线程安全的:由于编译器的优化,允许出现主存和线程工作内存数据不一致问题,这就是“DCL失效”的问题,并不能保证这个双重检查锁定习语有效。它偶尔会失败,而不是总失败。具体原因请参详
http://www.ibm.com/developerworks/cn/java/j-dcl.html。
JAVA语言提供内部静态类,我们可以基于内部静态类的特性,改进饱汉式单例模式,提供一种高效而安全的单例模式,代码如下:
/**
* StaticInnerClassSingletonPatternTest
* 基于内部静态类的单例模式
*/
public class StaticInnerClassSingletonPatternTest{
private StaticInnerClassSingletonPatternTest{}
//定义一个私有的内部静态类并在其中初始化外部单例对象
private static class SingletonHolder{
static final StaticInnerClassSingletonPatternTest INSTANCE = new StaticInnerClassSingletonPatternTest();
}
//只能通过该方法获取类的实例对象
public static StaticInnerClassSingletonPatternTest getInstance(){
return StaticInnerClassSingletonPatternTest.INSTANCE;
}
}
通过静态内部类的方式生成的单例模式,既保证了线程安全的,有保证了延迟加载。
在JDK发展到JDK 5.0之后,volatile + synchronized可以在保证内存模型的三个特性,即可见性、原子性和顺序性之外,对于被定义为volatile的变量,又禁用了volatile变量的重排序优化,就可以通过如下方式生成的单例模式,既保证安全性又兼顾延迟加载的功能,代码如下:
/**
* NewDoubleCheckerSingletonPatternTest
* volatile + synchronized的“双重检查锁”饱汉式单例模式
*/
public class NewDoubleCheckerSingletonPatternTest{
private static volatile NewDoubleCheckerSingletonPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private NewDoubleCheckerSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static NewDoubleCheckerSingletonPatternTest getInstance(){
if(instance == null){
synchronized(NewDoubleCheckerSingletonPatternTest.class){
if(instance == null){
new DoubleCheckerSingletonPatternTest();
}
}
}
return instance;
}
}
分享到:
相关推荐
内容概要:本文档介绍了三个经典的软件设计模式——单例模式(Singleton Pattern)、工厂模式(Factory Pattern)以及观察者模式(Observer Pattern)的具体实现,并给出了带有详细注释的C++代码范例。对每个设计模式都有...
单例模式有多种实现方式,其中比较常见的有饿汉式、懒汉式、双重检查锁定等。 工厂设计模式是一种创建型设计模式,它的主要目标是将对象的创建和使用分离,使得代码更具有可维护性和可扩展性。该模式通常会定义一个...
本文将聚焦于创建型设计模式,特别是单例模式和原型模式,这两种模式在对象的创建方面扮演着重要的角色。 单例模式是一种限制类实例化次数的设计模式,确保在整个应用程序中,一个类只有一个实例存在。这在某些场景...
"设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...
单例模式主要有懒汉式和饿汉式两种实现,饿汉式不会有线程安全的问题,但是提前构造对象占用了一定的资源,如果对内存要求较低的场景可以使用饿汉式实现;懒汉式应使用DCL机制来避免多线程竞争资源的问题,并且懒汉...
本文实例讲述了JS 设计模式之:单例模式定义与实现方法。分享给大家供大家参考,具体如下: 良好的设计模式可以显著提高代码的可读性,降低复杂度和维护成本。笔者打算通过几篇文章通俗地讲一讲常见的或者实用的设计...
02_JavaSE面试题:单例设计模式
本资源“一例读懂设计模式-单例模式、简单工厂模式.zip”旨在帮助初学者通过实例深入理解这两种重要设计模式:单例模式和简单工厂模式。以下是关于这两个模式的详细讲解。 1. **单例模式**: 单例模式是一种限制类...
**Java设计模式:单例模式详解** 单例模式是软件设计中的一种常见模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式在控制资源的共享、提高性能或协调多个组件之间的交互等方面有着广泛的应用。 ##...
软件体系结构实验报告
单例模式是一种保证一个类只有一个实例并提供全局访问点的设计模式。它的主要目的是控制类的实例化过程,避免因为大量的实例化导致的系统资源浪费,特别适用于那些需要频繁创建和销毁的对象。实现单例模式通常有饿汉...
本项目涵盖了四种常见的设计模式:单例模式、工厂模式、动态代理和适配器模式。下面将详细阐述这四种设计模式的概念、作用以及在实际项目中的应用。 **1. 单例模式** 单例模式是一种限制类实例化次数为一个的设计...
单例模式的实现饿汉式懒汉式线程安全的懒汉式登记式单例模式的优缺点单例模式的优点单例模式的缺点 单例模式是23个模式中比较简单的模式,应用也非常广泛 什么是单例模式? 单例模式的定义: Ensure a class ...
在给定的标题和描述中,我们关注的是两种重要的设计模式:单例模式和观察者模式。 首先,让我们深入了解单例模式。单例模式是一种确保一个类只有一个实例,并提供全局访问点的设计模式。这种模式在资源管理、缓存、...
【设计模式概述】 ...总的来说,单例模式、工厂模式和观察者模式都是Java中非常实用的设计模式,它们在实际开发中有着广泛的应用。理解并熟练掌握这些模式,可以帮助开发者编写出更加高效、可维护的代码。
单例模式是软件设计模式中的一种经典模式,它主要用于控制类的实例化过程,确保一个类在整个应用程序中只有一个实例存在。这种模式在Java编程中非常常见,特别是在需要频繁实例化然后销毁的对象,或者需要共享资源的...
单例模式(Singleton Pattern)作为创建型模式中的一种,旨在确保一个类在系统中只有一个实例,并提供全局访问点。
1. 单例模式: 单例模式确保一个类只有一个实例,并提供全局访问点。在Java等编程语言中,通常通过私有构造函数和静态工厂方法来实现。这种模式常用于控制资源的共享,如数据库连接或线程池。 2. 简单工厂模式: ...
在这个文档中,我们关注的是三种设计模式:单例模式、适配器模式和工厂模式。 首先,单例模式是一种确保一个类只有一个实例并提供一个全局访问点的设计模式。这种模式的核心在于控制类的实例化过程,确保在任何情况...
单例模式是设计模式中的一种,它在Java编程中被广泛应用,主要目的是限制类的实例化,确保在程序运行期间,对于某个特定类,只存在一个全局共享的对象。这种模式通常用于那些需要频繁实例化然后销毁,或者创建代价...