`
wangdongsong
  • 浏览: 36018 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

学习设计模式系列之——单例模式(Java)

阅读更多

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
 其实,GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

在单例模式中,有三种实现方式:1、饿汉式;2、懒汉式;3、双重检查,下面我们分别来看这三种方式。

 

/**
 *
 * Person.java
 * sxt_Singleton
 * 2010-7-7 下午09:22:32
 */

/** 
 * 饿汉式单例模式
 * 线程永远是安全的
 * 在单线程和多线程中可以保持单例
 * 2010-7-7 下午09:22:32
 */
public class Person {
	
	public static final Person person=new Person();
	
	/**
	 * 姓名
	 */
	private String name;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * private Constructor
	 * Person.java
	 * 2010-7-7 下午09:25:52
	 */
	private Person() {
	}
	
	/**
	 * 提供一个全局的静态方法
	 */
	public static Person getPerson(){
		return person;
	}
}


主类的访问是:
		/*
		 * 饿汉式
		 */
		Person per=Person.getPerson();
		Person per2=Person.getPerson();
		per.setName("xiao");
		per2.setName("dai");
		
		System.out.println(per.getName());
		System.out.println(per2.getName());

 上述的是饿汉式,接下来我们看懒汉式

/** 
 * 懒汉式单例模式
 * 不能保证多线程中保证单例
 * 2010-7-7 下午09:22:32
 */
public class Person2 {
	
	/**
	 * 姓名
	 */
	private String name;
	
	private static Person2 person;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * private Constructor
	 * Person.java
	 * 2010-7-7 下午09:25:52
	 */
	private Person2() {
	}
	
	/**
	 * 提供一个全局的静态访问方法
	 */
	public static Person2 getPerson(){
		/*
		 * 当A线程运行到if(person==null)时,person为null,因此执行person= new Person2();
		 * 此时,B线程也正好执行到if(person==null),但A线程还没有产生Person2的实例
		 * 因此B线程又一次执行了person= new Person2()
		 */
		if(person==null){
			person= new Person2();
		}
		return person;
	}
}

  由于懒汉式不能保证线程的安全性,因为我们对其进行改造,改造过后的代码如下:

/** 
 * 对Person2进行改造之后的Person3
 * 2010-7-7 下午09:22:32
 */
public class Person3 {
	
	private static Person3 person;
	
	/**
	 * 姓名
	 */
	private String name;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * private Constructor
	 * Person.java
	 * 2010-7-7 下午09:25:52
	 */
	private Person3() {
	}
	
	/**
	 * 加入同步关键字,解决Person2多线程访问的问题
	 * 对整个方法同步的时候,效率比较低,解决方法看Person4
	 * 对整个方法时行同步,那么if(person==null)每次都要执行
	 * 提供一个全局的静态方法
	 */
	public static synchronized Person3 getPerson(){
		if(person==null){
			person= new Person3();
		}
		return person;
	}
}

 在Person3中,我们加入了同步关键字,但是效率不高,经过我们的改造,产生了Person4,代码如下:

/** 
 * 双得检查单例模式
 * 在单线程和多线程中可以保持单例
 * 2010-7-7 下午09:22:32
 */
public class Person4 {
	
	private static Person4 person;
	
	/**
	 * 姓名
	 */
	private String name;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * private Constructor
	 * Person.java
	 * 2010-7-7 下午09:25:52
	 */
	private Person4() {
	}
	
	/**
	 * 加入同步关键字,解决Person2多线程访问的问题
	 * 同步关键没有在方法级加,是因为考虑到效率问题
	 * 采用同步代码块,保证了if(person==null)里面的代码只运行一次
	 * 例如:当A线程执行到if(person==null),此时person为null,因为执行同步代码块中的代码
	 * 同时,B线程也执行到了if(person==null),而A还没有产生Person4的实例,因此也执行同步代码块中的代码
	 * A结束以后,B开始,可是,person已经产生,那么B线程就会再执行person=new Person4()
	 * 那么在接下来的线程,如C、D线程,判断if(person==null)时,person已经不在是null了
	 * 那么方法直接返回
	 * 所在相对于Person3中的代码来说效率高
	 * 提供一个全局的静态方法
	 */
	public static  Person4 getPerson(){
		if(person==null){
			/*
			 * 同步代码块只会执行一次
			 * 因此相对于Person3,效率比较高
			 */
			synchronized(Person4.class){
				if(person==null){
					person=new Person4();
				}
			}
		}
		return person;
	}
}

 至此,三种实现方式如下所述。

单例保证了一处程序内,只有一个实例。

0
0
分享到:
评论
1 楼 mercyblitz 2010-07-08  
引用

public class Person4 { 
      
     private static Person4 person; 



你的double lock check 是错的,应该需要加一个volatile给Person4单例对象。

相关推荐

    设计模式——单例模式

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

    java设计模式之——单例模式

    单例模式是软件设计模式中的一种经典模式,其主要目的是控制类的实例化过程,确保在任何情况下,一个类只有一个实例存在。这种模式通常用于管理共享资源或者全局配置,例如数据库连接池、线程池、日志服务等。在Java...

    设计模式实现——单例模式

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制共享资源、管理系统级别的服务或者简化对象间的交互。单例模式的核心在于...

    设计模式——单例模式(懒汉模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类在任何情况下都只有一个实例存在。这个模式在很多场景下非常有用,例如控制全局资源、管理配置信息等。本文将详细探讨单例模式的懒汉式实现,并结合源码进行解析...

    java设计模式——单例模式

    【Java设计模式——单例模式】 单例模式是一种常见的软件设计模式,它的核心思想是确保在应用程序的整个生命周期中,某个类只有一个实例存在。这种模式主要用于控制类的实例化过程,减少系统资源的消耗,提高系统...

    设计模式之单例模式Java实现和类设计图

    本次我们将深入探讨两种设计模式——单例模式和装饰模式,它们在Java编程中都有着广泛的应用。 首先,让我们来理解“单例模式”。单例模式是一种创建型设计模式,其核心思想是保证一个类只有一个实例,并提供一个...

    三种工厂设计模式和两种单例模式

    在本文中,我们将深入探讨三种工厂设计模式——简单工厂模式、抽象工厂模式和工厂方法模式,以及两种单例模式——饿汉单例模式和懒汉单例模式。这些模式都是面向对象设计中的重要组成部分,对于理解和构建可维护、可...

    设计模式-Java语言中的应用(pdf)

    通过深入学习《设计模式——Java语言中的应用》,开发者能够更好地理解和应用这些模式,从而编写出更加高效、可扩展的Java程序。无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    设计模式-单例模式

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

    Java设计模式源代码——自己看pdf写的

    以上只是部分Java设计模式的介绍,实际的“DesignPatterns”压缩包可能包含了这些模式的源代码实现,通过阅读和学习这些代码,开发者可以更好地理解和运用设计模式,提升代码质量。同时,结合博主提供的博客链接,...

    java设计模式-单例.pdf

    ### Java设计模式——单例模式详解 #### 一、单例模式概述 单例模式是设计模式中的一个重要组成部分,属于创建型模式之一。其主要作用是确保某个类仅有一个实例存在,并提供一个全局访问该实例的方法。这在很多场景...

    设计模式——单实例模式、单件模式——Java编写

    单实例模式是软件设计模式中的一种,它的核心思想是确保一个类在整个系统运行过程中只有一个实例存在,并提供一个全局访问点,以保证所有对该类对象的访问都指向这个唯一的实例。这种模式在Java中广泛应用于配置管理...

    设计模式——JAVA.docx

    ### JAVA设计模式总结之23种设计模式及六大原则 #### 一、设计模式之六大原则 ##### 总原则:开闭原则(Open Close Principle) 开闭原则是设计模式中最核心的原则之一,它强调的是软件实体(类、模块、函数等)...

    Java与模式——源码

    《Java与模式——源码》这个主题涉及到的是Java编程语言中的设计模式应用,以及如何通过源代码来理解和学习这些模式。设计模式是软件工程中的一种最佳实践,它们是解决常见问题的经验总结,使得代码更易读、易维护、...

    java设计模式经典教程

    设计模式的概念最早出现在1994年出版的《设计模式——可复用面向对象软件的基础》一书中,该书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者合著,他们也因此被称为“GOF”(Gang of Four)...

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

Global site tag (gtag.js) - Google Analytics