Java设计模式之单例模式

原创 2017年05月15日 22:39:02

单例模式(Singletonpattern):确保一个类只有一个实例,并提供全局访问点,这个类也被称为单例类。

单例模式的特点:

1、单例类只能有一个实例;

2、单例类必须自己创建自己的唯一实例;

3、单例类必须给所有其他对象提供这一个实例。


单例模式又细分为:饿汉式懒汉式两种情况。

饿汉式单例类:

public class HungerSingleton {
	 /** 
     * 构造方法私有化
     */  
    private HungerSingleton(){}  
	
    //创建类的唯一实例
    private static HungerSingleton instance = new HungerSingleton();  
   
    /** 
     * 提供一个获取实例的类方法
     */  
    public static HungerSingleton getInstance(){  
        return instance;  
    }  
}

       饿汉单例类在被加载时,静态变量instance就会被初始化,此时私有的构造方法会被调用,完了之后单例类的唯一实例就会被创建出来。用饿汉式来形容很形象,既然饿那么实例就创建得比较着急,在装载类是就创建了实例。

饿汉式就是用空间换时间:当类装载的时候就会创建类的实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断,节省了运行时间。


懒汉式单例类:

public class LazySingleton {
	  /** 
     * 构造方法私有化
     */  
    private LazySingleton(){}  
    
    //创建类的唯一实例
    private static LazySingleton instance = null;  
    
    /** 
     * 提供一个获取实例的类方法
     */  
    public static LazySingleton getInstance(){  
        if(instance == null){  
            instance = new LazySingleton();  
        }  
        return instance;  
    }  
}

       懒汉式跟饿汉式的区别就在于,当懒汉式单例类在被加载时并没有创建出instance实例,只是声明了一下。既然是懒嘛,那就创建得比较慢,当别的对象需要使用的时候,再进行创建。


懒汉式就是用时间换空间:就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。


我们创建一个测试类稍微测试一下:

public class SingletonTest {
	public static void main(String[] args) {
		//饿汉式
		HungerSingleton h1 = HungerSingleton.getInstance();
		HungerSingleton h2 = HungerSingleton.getInstance();
		if(h1==h2){
			System.out.println("s1和s2是同一个实例!");
		}else{
			System.out.println("s1和s2不是同一个实例!");
		}
		//懒汉式
		LazySingleton l1 = LazySingleton.getInstance();
		LazySingleton l2 = LazySingleton.getInstance();
		if(l1==l2){
			System.out.println("l1和l2是同一个实例!");
		}else{
			System.out.println("l1和l2不是同一个实例!");
		}
	}
}

运行结果为:


事实证明,他们都只能存在一个实例。


接下来我们来分析一下饿汉式懒汉式的区别:

饿汉式:加载类时比较慢,但运行时获取对象的速度比较快,线程是安全的;

懒汉式:加载类时比较快,但运行时获取对象的速度比较慢,线程是不安全的


那么怎么来解决懒汉式的线程安全呢?

       在这里我们可以使用双重检查加锁

       可以使用“双重检查加锁”的方式来实现,就可以既实现线程安全,又能够使性能不受很大的影响。那么什么是“双重检查加锁”机制呢?

所谓“双重检查加锁”机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块,这是第一重检查,进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。


       “双重检查加锁”机制的实现会使用关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。


  注意:在java1.4及以前版本中,很多JVM对于volatile关键字的实现的问题,会导致“双重检查加锁”的失败,因此“双重检查加锁”机制只只能用在java5及以上的版本。


懒汉式单例类被稍加工后:



       synchronized是线程同步的修饰符,了解过多线程就知道,它的作用域越小越好。

       提示由于volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,所以运行效率并不是很高。因此一般建议,没有特别的需要,不要使用。也就是说,虽然可以使用“双重检查加锁”机制来实现线程安全的单例,但并不建议大量采用,可以根据情况来选用。


版权声明:欢迎以任何形式转载,但请注明作者和出处

java 单例设计模式使用场景

单例设计模式的使用场景说明,优缺点,在线程中该使用那种方式的单例,其中涉及到类在JVM中的分配......
  • bob_Xing_Yang
  • bob_Xing_Yang
  • 2017年05月23日 10:53
  • 387

大话设计模式——单例模式

宏观导图 细节展示  单例模式的结构图: 关键代码:  在GetInstance方法中,要加入判断。 if (instance==null) { instance=new Single...
  • u011500356
  • u011500356
  • 2015年01月05日 21:44
  • 1472

Android面试设计模式之单例模式

在面试的时候面试官会问我们常用的一些设计模式,这里先介绍一下单例模式。 为什么要使用单例模式 1.控制资源的使用,通过线程同步来控制资源的并发访问; 2.控制实例产生的数量,达到节约系统资源; 3...
  • qq_435559203
  • qq_435559203
  • 2016年09月12日 18:25
  • 582

设计模式之——单例模式(Singleton)的实现、优缺点和常见应用场景

一.单例模式的三种实现 以及各自的优缺点 转载自http://my.oschina.net/suyewanwan/blog/102525 单例模式:单例模式的意思就是只有一个实例。单例模式确保某...
  • qq_30465427
  • qq_30465427
  • 2015年08月09日 15:36
  • 1209

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

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

java设计模式之单例模式(几种写法及比较)

概念:   java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。   单例模式有以下特点:   1、单例类只能有一个实例。  ...
  • tolcf
  • tolcf
  • 2015年10月21日 22:56
  • 6284

浅谈JAVA设计模式之——单例模式(Singleton)

一、概述        保证一个类仅有一个实例,并提供一个访问它的全局访问点。 二、适用性      1.当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。      2.当这个唯一...
  • l1028386804
  • l1028386804
  • 2015年05月02日 17:50
  • 1091

Java四种单例设计模式

Java中的四种单例模式单例模式是最容易理解的设计模式之一,介绍Java中单例模式的四种写法。1.饿汉式单例模式public class Singleton{ private static S...
  • twocold_2010
  • twocold_2010
  • 2016年11月20日 15:13
  • 291

浅谈常见设计模式--单例模式 简单工厂模式

今题那站在这里和大家一起分享最近在一本书上看到的关于设计模式的内容,接下来要讲的设计模式有: 单例模式 简单工厂模式 工厂方法和抽象工厂 代理模式 命令模式 策略模式 门面模式 桥接模式 观察者模式 ...
  • xikai18827083487
  • xikai18827083487
  • 2016年11月13日 17:04
  • 987

Java设计模式菜鸟系列(六)单例模式建模与实现

单例模式保证了一个类只有一个实例,且提供一个访问全局点的方式,更加灵活的保证了实例的创建和访问约束。系统中只有一个实例,因此构造方法应该为私有 饿汉式:类加载时直接创建静态实例;懒汉式:第一次需要时才...
  • JAVE_LOVER
  • JAVE_LOVER
  • 2014年10月05日 00:44
  • 2504
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java设计模式之单例模式
举报原因:
原因补充:

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