- 浏览: 197795 次
- 性别:
- 来自: 上海
文章分类
最新评论
模式的用途是 "ensure a class has only one instance, and provide a global point of access to it"(确保每个类只有一个实例,并提供它的全局访问点)。
在此类系统中,在任何给定时间只应运行一个类或某个类的一组预定义数量的实例。 例如,当使用某个类来维护增量计数器时,此简单的计数器类需要跟踪在多个应用程序领域中使用的整数值。 此类需要能够增加该计数器并返回当前的值。 对于这种情况,所需的类行为应该仅使用一个类实例来维护该整数,而不是使用其它类实例来维护该整数。
单例模式主要有3个特点,:
1、单例类确保自己只有一个实例。
2、单例类必须自己创建自己的实例。
3、单例类必须为其他对象提供唯一的实例。
单例模式的实现方式:懒汉单例类和饿汉单例类
单例模式的实现有多种方法,常见的就有懒汉式单例类和饿汉式单例类。我们前面介绍的实现方法就属于懒汉式单例类。
懒汉式单例类 延迟实例化(lazy instantiaze)
对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备。它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。
懒汉模式只在外部对象第一次请求实例的时候才去创建。
饿汉式单例
对于饿汉模式,我们可以这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。
单例模式也是一种比较常见的设计模式,它到底能带给我们什么好处呢?其实无非是三个方面的作用:
第一、控制资源的使用,通过线程同步来控制资源的并发访问;
第二、控制实例产生的数量,达到节约资源的目的。
第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。
1.数据库连接池的设计一般采用单例模式
2.常用的文件管理器。由于Windows操作系统是一个典型的多进程多线程系统,那么在创建或者删除某个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象。采用单例模式设计的文件管理器就可以完美的解决这个问题,所有的文件操作都必须通过唯一的实例进行,这样就不会产生混乱的现象。
3.大多数的操作系统最终为打印任务设计了一个单例模式的假脱机服务Printer Spooler,所有的打印任务都需要通过假脱机服务进行
4.,配置信息类、管理类、控制类、门面类、代理类通常被设计为单例类。像Java的Struts、Spring框架,.Net的Spring.Net框架,以及Php的Zend框架都大量使用了单例模式
一)。使用立即创建实例,而不用延迟实例化的做法
1。使用全局变量
在这种方法中,公有静态成员是一个final域(保证了总是包含相同的对象引用)。私有构造函数仅被调用一次,用来实例化公有的静态final域 Singleton.uniqueInstace。由于缺少公有的或者受保护的构造函数,所有保证了Singleton的全局唯一性:一旦 Singleton类被实例化之后,只有一个Singleton实例存在——不多也不少。使用此Singleton类的程序员的任何行为都不能改变这一点。
2。使用公有的静态工厂方法
第二种方法提供了一个公有的静态工厂方法,而不是公有的静态final域。利用这个做法,我们依赖JVM在加载这个类时马上创建此类唯一的一个实例。JVM保证任何线程访问uniqueInstance静态变量之前,一定先创建此实例。
二)。使用延迟实例化的做法(使用公有的静态工厂方法)
1。非线程安全的
先利用一个静态变量uniqueInstance来记录Singleton类的唯一实例,当我们要使用它的实例时,如果它不存在,就利用私有的构 造器产生一个Singleton类的实例并把它赋值到uniqueInstance静态变量中。而如果我们不需要使用这个实例,它就永远不会产生。这就 是"延迟实例化(lazy instantiaze)"。但上面这段程序在多线程环境中是不能保证单个实例的。
2。多线程安全的
public class Singleton {
private static Singleton uniqueInstance ;
private Singleton(){
}
public synchronized static Singleton getInSingleton(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
//...Remainder omitted
}
通过给getInstance()方法增加synchronized关键字,也就是给getInstance()方法线程加锁,迫使每次只能有一 个线程在进入这个方法,这样就可以解决上面多线程产生的灾难了。但加锁的同步方法可能造成程序执行效率大幅度下降,如果你的程序对性能的要求很高,同时你 的getInstance()方法调用的很频繁,这时可能这种设计也不符合程序要求了。其实这种加锁同步的方法用在这确实有一定的问题存在,因为对 Singleton类来说,只有在第一次执行getInstance()方法时,才真正的需要对方法进行加锁同步,因为一旦第一次设置好 uniqueInstance变量后,就不再需要同步这个方法了。之后每次调用这个方法,同步反而成了一种累赘。
3。 用"双重检查加锁",在getInstance()方法中减少使用同步:
对于双重检查加锁(Double-Checked Locking)有一篇文章解释的很深入:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
在此类系统中,在任何给定时间只应运行一个类或某个类的一组预定义数量的实例。 例如,当使用某个类来维护增量计数器时,此简单的计数器类需要跟踪在多个应用程序领域中使用的整数值。 此类需要能够增加该计数器并返回当前的值。 对于这种情况,所需的类行为应该仅使用一个类实例来维护该整数,而不是使用其它类实例来维护该整数。
单例模式主要有3个特点,:
1、单例类确保自己只有一个实例。
2、单例类必须自己创建自己的实例。
3、单例类必须为其他对象提供唯一的实例。
单例模式的实现方式:懒汉单例类和饿汉单例类
单例模式的实现有多种方法,常见的就有懒汉式单例类和饿汉式单例类。我们前面介绍的实现方法就属于懒汉式单例类。
懒汉式单例类 延迟实例化(lazy instantiaze)
对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备。它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。
懒汉模式只在外部对象第一次请求实例的时候才去创建。
饿汉式单例
对于饿汉模式,我们可以这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。
单例模式也是一种比较常见的设计模式,它到底能带给我们什么好处呢?其实无非是三个方面的作用:
第一、控制资源的使用,通过线程同步来控制资源的并发访问;
第二、控制实例产生的数量,达到节约资源的目的。
第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。
1.数据库连接池的设计一般采用单例模式
2.常用的文件管理器。由于Windows操作系统是一个典型的多进程多线程系统,那么在创建或者删除某个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象。采用单例模式设计的文件管理器就可以完美的解决这个问题,所有的文件操作都必须通过唯一的实例进行,这样就不会产生混乱的现象。
3.大多数的操作系统最终为打印任务设计了一个单例模式的假脱机服务Printer Spooler,所有的打印任务都需要通过假脱机服务进行
4.,配置信息类、管理类、控制类、门面类、代理类通常被设计为单例类。像Java的Struts、Spring框架,.Net的Spring.Net框架,以及Php的Zend框架都大量使用了单例模式
一)。使用立即创建实例,而不用延迟实例化的做法
1。使用全局变量
//Singleton with final field public class Singleton { public static final Singleton uniqueInstance = new Singleton(); private Singleton(){ } //...Remainder omitted }
在这种方法中,公有静态成员是一个final域(保证了总是包含相同的对象引用)。私有构造函数仅被调用一次,用来实例化公有的静态final域 Singleton.uniqueInstace。由于缺少公有的或者受保护的构造函数,所有保证了Singleton的全局唯一性:一旦 Singleton类被实例化之后,只有一个Singleton实例存在——不多也不少。使用此Singleton类的程序员的任何行为都不能改变这一点。
2。使用公有的静态工厂方法
//Singleton with static factory public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton(){ } public static Singleton getInSingleton(){ return uniqueInstance; } //...Remainder omitted }
第二种方法提供了一个公有的静态工厂方法,而不是公有的静态final域。利用这个做法,我们依赖JVM在加载这个类时马上创建此类唯一的一个实例。JVM保证任何线程访问uniqueInstance静态变量之前,一定先创建此实例。
二)。使用延迟实例化的做法(使用公有的静态工厂方法)
1。非线程安全的
public class Singleton { private static Singleton uniqueInstance ; private Singleton(){ } public static Singleton getInSingleton(){ if(uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } //...Remainder omitted }
先利用一个静态变量uniqueInstance来记录Singleton类的唯一实例,当我们要使用它的实例时,如果它不存在,就利用私有的构 造器产生一个Singleton类的实例并把它赋值到uniqueInstance静态变量中。而如果我们不需要使用这个实例,它就永远不会产生。这就 是"延迟实例化(lazy instantiaze)"。但上面这段程序在多线程环境中是不能保证单个实例的。
2。多线程安全的
public class Singleton {
private static Singleton uniqueInstance ;
private Singleton(){
}
public synchronized static Singleton getInSingleton(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
//...Remainder omitted
}
通过给getInstance()方法增加synchronized关键字,也就是给getInstance()方法线程加锁,迫使每次只能有一 个线程在进入这个方法,这样就可以解决上面多线程产生的灾难了。但加锁的同步方法可能造成程序执行效率大幅度下降,如果你的程序对性能的要求很高,同时你 的getInstance()方法调用的很频繁,这时可能这种设计也不符合程序要求了。其实这种加锁同步的方法用在这确实有一定的问题存在,因为对 Singleton类来说,只有在第一次执行getInstance()方法时,才真正的需要对方法进行加锁同步,因为一旦第一次设置好 uniqueInstance变量后,就不再需要同步这个方法了。之后每次调用这个方法,同步反而成了一种累赘。
3。 用"双重检查加锁",在getInstance()方法中减少使用同步:
public class Singleton { // volatile关键字确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量 private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getInSingleton() { if (uniqueInstance == null) {// 检查实例,如是不存在就进行同步代码区 synchronized (Singleton.class) {// 对其进行锁,防止两个线程同时进入同步代码区 if (uniqueInstance == null) {// 双重检查,非常重要,如果两个同时访问的线程,当第一线程访问完同步代码区后,生成一个实例;当第二个已进入getInstance方法等待的线程进入同步代码区时,也会产生一个新的实例 uniqueInstance = new Singleton(); } } } return uniqueInstance; } // ...Remainder omitted }
对于双重检查加锁(Double-Checked Locking)有一篇文章解释的很深入:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
发表评论
-
Java 5 并发学习(转)
2012-06-26 14:38 859Java 5 并发学习 在Java5之后,并发线程这块发生 ... -
WeakHashMap和HashMap的区别
2012-02-24 13:42 843http://mzlly999.iteye.com/blog/ ... -
volatile 的高级模式
2012-02-22 13:07 732前面几节介绍的模式涵盖了大部分的基本用例,在这些模式中使用 v ... -
The "Double-Checked Locking is Broken" Declaration
2012-02-22 10:34 959http://www.cs.umd.edu/~pugh/jav ... -
Log4j配置文件详细说明[转]
2012-02-14 10:48 1345属性文件Properties properties属性文件 ... -
Log4j的配置文件
2012-02-14 10:42 812Log4j支持两种配置文件格式,一种是java属性文件(键—值 ... -
单例模式的俩种方式
2012-01-04 14:09 923等等 单例模式的俩种方式: 饿汉式 class Singlet ... -
Mysql连接数据库:PreparedStatement.addBatch()方法
2011-12-23 08:43 58181.Eclipse连接MySQL数据库 mysql>C ... -
java中ArrayList 、LinkList区别
2011-12-21 15:30 1170java中ArrayList 、LinkList、List区别 ... -
Thread的实现
2011-12-21 14:25 1203Making a Thread A thread in Jav ... -
Date4j,一个简约的日期处理类库
2011-12-14 10:13 834Java本身的日期类在JDK1.0版本之后就再也没有更新过,同 ... -
How to use Log4j
2011-09-29 13:57 8081. LogManager.getInstance().get ... -
重写hashCode和equals方法(转)
2011-09-27 09:58 1132如果你的对象想散列存 ... -
学习Enum转
2011-09-22 14:11 8731. 关于 Java Enum: 学过 C/C++ 等 ... -
PO BO VO DTO POJO DAO概念及其作用(转)
2011-09-20 09:49 663J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨 ... -
Thread的实现
2011-09-20 09:47 857Thread的实现 1.extend Thread,then ... -
Adapter模式(转)
2011-08-17 15:48 885[b]GOF《设计模式》一书对Adapter模式是这样描述的: ... -
JVM常见配置汇总
2011-08-15 14:56 1904从这个图中可以看到, ... -
Abstract or Interface
2011-08-11 15:02 726详解java中的抽象类和接 ... -
HashMap HashTable TreeMap
2011-08-11 13:45 964Map中我们通过对象来对对象进行索引,用来索引的对象叫做key ...
相关推荐
### C++中实现Singleton模式的关键知识点 #### 一、Singleton模式简介 Singleton模式是一种常用的软件设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中经常被用于控制对共享资源...
**C++实现的Singleton模式详解** Singleton模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,例如管理共享资源,如数据库连接池,或者确保某个...
### Java的Singleton模式详解 #### 一、Singleton模式概述 Singleton模式是一种常用的设计模式,在Java中主要用于确保一个类只有一个实例,并提供一个全局访问点。这种模式对于管理共享资源(如数据库连接池、...
### 最简单的设计模式学习:Singleton模式 #### 一、Singleton模式简介 Singleton(单例)模式是一种常用的软件设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在许多场合下非常...
Singleton模式是设计模式中的一种创建型模式,它在软件工程中扮演着重要的角色。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点来获取这个唯一的实例。Singleton模式的应用场景通常涉及到系统...
Singleton模式: 确保一个类只有唯一的一个实例。 Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton...
Singleton模式是一种设计模式,它是创建型模式的一种,用于控制类的实例化过程,确保一个类在整个应用程序中只有一个实例存在。这种模式在系统中需要频繁创建和销毁对象,且对象需要共享资源时非常有用,比如配置...
《C#设计模式之Singleton模式详解》 Singleton模式是软件设计模式中的一种基础模式,它在众多设计模式中占有重要地位,尤其在C#编程中经常被应用。Singleton模式的主要目的是确保一个类只有一个实例,并提供一个...
在Java编程中,Singleton模式是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。线程安全的Singleton模式对于多线程环境尤为重要,因为它可以防止多个线程同时创建多个实例。本文将详细介绍...
【深入浅出单例Singleton模式】 单例模式是一种在软件设计中常见的设计模式,它的核心目标是确保一个类只有一个实例,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于控制资源的共享,如全局...
这里我们将深入探讨三种常见的Java设计模式:单例(Singleton)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)。 **单例模式(Singleton)** 单例模式确保一个类只有一个实例,并提供一个全局访问点...
双重检测锁(Double-Checked Locking)实现的Singleton模式在多线程应用中有相当的价值。在ACE的实现中就大量使用ACE_Singleton模板类将普通类转换成具有Singleton行为的类。这种方式很好地消除了一些重复代码臭味,...
综上所述,Qt Qml的Singleton模式为全局共享对象提供了方便,使得在Qml环境中管理和访问同一对象变得简单。通过C++和Qml的有效结合,我们可以构建出高效且易于维护的应用程序。了解和熟练运用Singleton模式,对于...
在Java中,Singleton模式的实现有多种方式,每种方式都有其优缺点,我们将详细探讨这些实现方法并进行对比。 ### 1. 饿汉式(Static Final Field) 这是最简单的Singleton实现方式,通过静态初始化器在类加载时就...
接下来,我们将深入探讨Java Singleton模式的实现方式、优缺点以及使用场景。 一、Singleton模式的实现 1. 饿汉式(静态常量) ```java public class Singleton { private static final Singleton INSTANCE = ...
单态模式(Singleton模式)是Java设计模式中的一种,它的主要目标是确保一个类在整个应用程序中只有一个实例存在。这种模式的应用场景广泛,特别是在需要全局共享的资源管理、配置中心、日志服务等场合非常常见。 ...