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

转载 2015年07月07日 19:42:10

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

一、饿汉模式

饿汉模式代码  收藏代码
  1. /**  
  2.  * @ClassName: Singleton_Simple  
  3.  * @Description: 单例模式——饿汉模式   
  4.  * @author Ran  
  5.  * @date 2011-2-4 上午12:46:15  
  6.  *   
  7.  */  
  8. public class Singleton_Simple {  
  9.       
  10.     private static final Singleton_Simple simple = new Singleton_Simple();  
  11.       
  12.     private Singleton_Simple(){}  
  13.       
  14.     public static Singleton_Simple getInstance(){  
  15.         return simple;  
  16.     }  
  17.   
  18. }  

    说明:顾名思义,饿汉模式就是在jvm进程启动并在我们主动使用该类的时候就会在内存中初始化一个单例对象,当我们调用getInstance()的时候直接获取该对象,他的创建是在我们调用getInstance()静态方法之前!

 

二、懒汉模式

懒汉模式代码  收藏代码
  1. /**  
  2.  * @ClassName: Singleton_lazy  
  3.  * @Description: 单例模式——懒汉模式   
  4.  * @author Ran  
  5.  * @date 2011-2-4 上午12:48:41  
  6.  *   
  7.  */  
  8. public class Singleton_lazy {  
  9.   
  10.     private static Singleton_lazy lazy = null;  
  11.       
  12.     private Singleton_lazy(){}  
  13.       
  14.     public static synchronized Singleton_lazy getInstance(){  
  15.         if( lazy == null ){  
  16.             lazy = new Singleton_lazy();  
  17.         }  
  18.         return lazy;  
  19.     }  
  20. }  

    说明:懒汉模式是相对于饿汉模式而言的,在jvm进程启动并在我们主动使用该类的时候不会在内存中初始化一个单例对象,只有当我们调用getInstance()的时候才去创建该对象,他的创建是在我们调用getInstance()静态方法之后,为了并没现象同步问题,我们在getInstance()方法上加了一个锁,这个方法每次只允许一个线程进来,虽然同步问题是解决了,但是相应的性能问题就出现了。

 

三、双锁机制

 

双锁机制 代码  收藏代码
  1. /**  
  2.  * @ClassName: Singleton_DoubleKey  
  3.  * @Description: 单例模式——双锁机制   
  4.  * @author Ran  
  5.  * @date 2011-2-4 上午12:53:50  
  6.  *   
  7.  */  
  8. public class Singleton_DoubleKey {  
  9.   
  10.     private static Singleton_DoubleKey doubleKey = null;  
  11.       
  12.     private Singleton_DoubleKey (){}  
  13.       
  14.     public static Singleton_DoubleKey getInstance(){  
  15.         if( doubleKey == null ){    //①  
  16.             synchronized(Singleton_DoubleKey.class){    //②  
  17.                 if( doubleKey == null ){    //③  
  18.                     doubleKey = new Singleton_DoubleKey();  //④  
  19.                 }  
  20.             }  
  21.         }  
  22.         return doubleKey;  
  23.     }  
  24. }  

     说明:双锁机制的出现是为了解决前面同步问题和性能问题,看上面的代码,简单分析下确实是解决了多线程并行进来不会出现重复new对象,而且也实现了懒加载,但是当我们静下来并结合java虚拟机的类加载过程我们就会发现问题出来了,对于JVM加载类过程不熟悉的,这里我简单介绍下,熟悉的跳过这段(当然,既然你熟悉就自然会知道双锁的弊端了)。

jvm加载一个类大体分为三个步骤:

  1. 加载阶段:就是在硬盘上寻找java文件对应的class文件,并将class文件中的二进制数据加载到内存中,将其放在运行期数据区的方法区中去,然后在堆区创建一个java.lang.Class对象,用来封装在方法区内的数据结构;
  2. 连接阶段:这个阶段分为三个步骤,步骤一:验证,验证什么呢?当然是验证这个class文件里面的二进制数据是否符合java规范咯;步骤二:准备,为该类的静态变量分配内存空间,并将变量赋一个默认值,比如int的默认值为0;步骤三:解析,这个阶段就不好解释了,将符号引用转化为直接引用,涉及到指针,这里不做多的解释;
  3. 初始化阶段:当我们主动调用该类的时候,将该类的变量赋于正确的值(这里不要和第二阶段的准备混淆了),举个例子说明下两个区别,比如一个类里有private static int i = 5; 这个静态变量在"准备"阶段会被分配一个内存空间并且被赋予一个默认值0,当道到初始化阶段的时候会将这个变量赋予正确的值即5,了解了吧!

好了,上面大体介绍了jvm类加载过程,回到我们的双锁机制上来分析下问题出在了哪里?假如有两个并发线程a、b,a线程主动调用了静态方法getInstance(),这时开始加载和初始化该类的静态变量,b线程调用getInstance()并等待获得同步锁,当a线程初始化对象过程中,到了第二阶段即连接阶段的准备步骤时,静态变量doubleKey 被赋予了一个默认值,但是这时还没有进行初始化,这时当a线程释放锁后,b线程判断doubleKey != null,则直接返回了一个没有初始化的doubleKey 对象,问题就出现在这里了,b线程拿到的是一个被赋予了默认值但是未初始化的对象,刚刚可以通过锁的检索!

 

所以对于上面的几个模式还是推荐使用第一种,在jvm加载类的时候就初始化一个对象,也避免了同步问题。

相关文章推荐

java设计模式之单例模式详解

  • 2012年11月02日 17:53
  • 33KB
  • 下载

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

  • 2017年02月07日 11:58
  • 9KB
  • 下载

JAVA设计模式之单例模式

概念:   java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。   单例模式有一下特点:   1、单例类只能有一个实例。   2、单例类必须自己自...

java 设计模式 单例模式

  • 2012年03月16日 22:45
  • 2KB
  • 下载

JAVA设计模式中的单例模式

  • 2009年02月24日 16:51
  • 3KB
  • 下载

Java设计模式--单例模式(Singleton)

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 类型:创建类模式 类图: 类图知识点: 1.类图分为三部分,依次是类名、属性、方法 2.以>结尾的为注释信息 3.修饰符+代表...

Java技术_每天掌握一种设计模式(002)_使用场景及简单实例(创建型:单例模式)

模式描述 一个类有且仅有一个实例,并且自行实例化并向整个系统提供。 2.模式作用 保证某个类在系统中只有一个实例对象,对于特殊需求来说非常必要。 限制了实例个数有利于GC的回收。...

Java设计模式 -- 单例模式

Java 设计模式之单例模式,懒汉式,饿汉式,双重检查锁定,Iodh方法
  • Hwaphon
  • Hwaphon
  • 2016年02月28日 10:40
  • 983

设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题

设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题 一:单例模式概念 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类...

Java实现设计模式之单例模式

单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java设计模式---单例模式
举报原因:
原因补充:

(最多只允许输入30个字)