[设计模式实践之路](1)单例模式

【简介】

单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点。

     实现单例模式的一个最好的方法就是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以创建,并且它可以提供一个访问该实例的方法。

【特点】

单例模式具有一下特点:

  • 单例类只有一个实例
  • 单例类必须自己创建自己的唯一实例
  • 单例类必须给所有其他对象提供这一实例

【分类】

主要的就是懒汉单例,饿汉单例

【懒汉单例】

package Mode;

/**
 * Java设计模式之单例模式
 * @author SJF0115
 *
 */
public class Singleton {

	private static Singleton instance;
	// 构造方法让其private,这就堵死了外界利用new创建此类实例的可能
	private Singleton() {
	}
	// 此方法是获得本实例的唯一全局访问点
	public static Singleton GetInstance(){
		// 若实例不存在,则new一个新实例,否则返回已有的实例
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Singleton s1 = Singleton.GetInstance();
		Singleton s2 = Singleton.GetInstance();
		if(s1 == s2){
			System.out.println("两个对象是相同的实例");
		}
		else{
			System.out.println("两个对象不是相同的实例");
		}
	}
}

这种写法lazy loading很明显,但是致命的是在多线程不能正常工作(多线程不安全)。

在类被加载的时候,唯一实例已经被创建。这个设计模式在Java中容易实现,在别的语言中难以实现。

【饿汉单例】

package Mode;

/**
 * Java设计模式之单例模式
 * @author SJF0115
 *
 */
public class Singleton {

	// 类装载时就实例化
	private static Singleton instance = new Singleton();
	// 构造方法让其private,这就堵死了外界利用new创建此类实例的可能
	private Singleton() {
	}
	// 此方法是获得本实例的唯一全局访问点
	public static Singleton GetInstance(){
		return instance;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Singleton s1 = Singleton.GetInstance();
		Singleton s2 = Singleton.GetInstance();
		if(s1 == s2){
			System.out.println("两个对象是相同的实例");
		}
		else{
			System.out.println("两个对象不是相同的实例");
		}
	}
}

这种方式基于classloder机制避免了多线程的同步问题,因此饿汉单例是线程安全的。

不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 

但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。

【懒汉单例(线程安全)】

package Mode;

/**
 * Java设计模式之单例模式
 * @author SJF0115
 *
 */
public class Singleton {

	private static Singleton instance;
	// 构造方法让其private,这就堵死了外界利用new创建此类实例的可能
	private Singleton() {
	}
	// 此方法是获得本实例的唯一全局访问点
	public static  Singleton GetInstance(){
		// 若实例不存在,则new一个新实例,否则返回已有的实例
		if(instance == null){
			synchronized(Singleton.class){
				if(instance == null){
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Singleton s1 = Singleton.GetInstance();
		Singleton s2 = Singleton.GetInstance();
		if(s1 == s2){
			System.out.println("两个对象是相同的实例");
		}
		else{
			System.out.println("两个对象不是相同的实例");
		}
	}
}

有人可能会疑问,在GetInstnce方法中为什么会有两次判断if(instance == null)。

回答:

对于instance存在的情况,就直接返回。不需要考虑线程问题。当instance为null时,就需要我们考虑多线程带来的问题。

假设当instance为null,并且同时有两个线程调用GetInstance()方法,他们都可以通过第一重instance == null的判断。

然后由于Synchronized机制,这两个线程只有一个进入,另一个在外排队等候,必须等先进入的线程结束之后,才能进入。

而此时如果没有第二重instance == null 判断,第一个线程进入后创建一个实例,第一个线程进入出来后,第二个线程终于等待结束,可以进入,

继续又创建了一个实例,这没有达到单例的目的。

时间: 2024-08-04 06:21:36

[设计模式实践之路](1)单例模式的相关文章

阿里巴巴CI:CD之分层自动化实践之路

6月29日,由阿里云研发协同RDC.阿里云云效和联合举办的"首届阿里巴巴研发效能嘉年华"上,阿里巴巴高级产品经理金桐带来"分层自动化实践之路"的演讲.本文从为什么要做自动化开始谈起,进而对分层自动化单元测试.业务服务层测试和UI测试进行优劣势分析,最后重点分享了阿里分层自动化的实践,包括工具分层和流程优化等.   直播视频请点击 随着云计算.大数据.AI智能等前沿科技的发展,传统的研发速度越来越难满足企业快速发展的需求,研发效能也成了继商业模式.技术突破之后的另一核

从 Spring Cloud 开始,聊聊微服务架构实践之路

本文讲的是从 Spring Cloud 开始,聊聊微服务架构实践之路[编者的话]随着公司业务量的飞速发展,平台面临的挑战已经远远大于业务,需求量不断增加,技术人员数量增加,面临的复杂度也大大增加.在这个背景下,平台的技术架构也完成了从传统的单体应用到微服务化的演进. 系统架构的演进过程 单一应用架构(第一代架构) 这是平台最开始的情况,当时流量小,为了节约成本,并将所有应用都打包放到一个应用里面,采用的架构为 .NET SQL Server: 表示层:位于最外层(最上层),最接近用户.用于显示数

项目DevOps研发云CI实践之路

本文讲的是项目DevOps研发云CI实践之路[编者的话]DevOps是Develop与Operations的缩写.DevOps不是凭空冒出来的,是我们持续集成思想的延伸. 使用敏捷或其他软件开发过程与方法,项目要求加快产品交付的速率,虚拟化和云计算基础设施(可能来自内部或外部供应商)日益普遍,都促使我们不断向DevOps方向发展. 因此,现在的业务开发,对传统的CI提出了更新更高的要求,借助于云技术,我们可以在DesOps趋势下实现从传统CI向云化CI的演变. 一.项目痛点 笔者所在项目在敏捷推

日志易:IT 运维分析及海量日志搜索的实践之路(上)

内容简介: IT运维分析(IT Operation Analytics, ITOA)是近年兴起,其把大数据技术应用于分析IT运维产生的大量数据,数据来源主要有日志.网络流量.植入代码.布点模拟监控等.过去使用数据库处理日志无法支持大数据量,后来出现了使用Hadoop/Storm/SparkStreaming等开发框架来处理日志,及最新的使用实时搜索分析引擎来对日志进行实时处理.现如今使用Hadoop/Storm/SparkStreaming等开发框架来处理日志已经在各大公司被广泛的运用,本次演讲

2014年四大最热门语言的实践之路

可以说这么说,在过去的一两年里编程领域迎来了翻天覆地的变化,如果说C,JAVA这些在过去几年里风靡全球,抢占Tiobe榜单,那么在如今移动领域兴起的年代 ,objetive-C也给Java造成很大的冲击.在编程领域可没有"一招鲜,吃遍天"的说法.因此对于开发者们来说,总是在不同的领域里 寻找着 合适的最佳语言. 那么反过来说,每种编程语言在不同的场景里,开发效率和执行效率都是有着天壤之别,比如说erlang适用于并行,PHP适用于WEB,R适用于统计,C#适用于界面等等,所以术业有专攻

颠覆传统,SaaS在中大型企业实践之路——No Software, Go SaaS

中国云计算产业最具影响力的盛会之一--2016杭州云栖大会(https://yunqi.aliyun.com/)将在云栖小镇召开.连续举办七届的云栖大会一直是业界了解阿里云计算生态发展和应用趋势.体验前沿技术和产品的最佳平台,来自海内外的上万名开发者.创业者聚集于此,分享着他们对云计算的思考与实践经验.7年来,从产品发布到行业解决方案展示,从关注技术到技术与服务并重,从单一的客户到生态全景的展现,大会的核心内容一直在"进化",而2016年杭州云栖大会,则以"飞天・进化&quo

PHP设计模式之工厂模式与单例模式_php技巧

本文实例讲述了PHP设计模式之工厂模式与单例模式实现方法.分享给大家供大家参考,具体如下: 设计模式简单说应对某类问题而设计的解决方式 工厂模式:应对需求创建相应的对象 class factory{ function __construct($name){ if(file_exists('./'.$name.'.class.php')){ return new $name; }else{ die('not exist'); } } } 单例模式:只创建一个对象的实例,不允许再创建实例,节约资源(

保险行业上云的正确姿势:天安人寿金融云实践之路

摘要:本期云栖说的主题是金融云与安全,我们都知道金融行业因为其特殊性往往成为关注的焦点,并且也往往会吸引众多黑客的目光.那么对于像天安人寿这样的保险行业企业来讲,如何实践自己的上云之路呢?上云又为他们带来了哪些便利呢?金融行业上云需要面对怎样的安全方面的考量呢?本期云栖说,天安人寿信息技术部总经理姚仁毅.资深架构师山虎.阿里云安全专家张伟伟以及阿里云保险行业总监戴飞飞将为您分享金融云与安全的那些事. 如果想更直观.更有意思地了解天安人寿金融云实践之路,还可以看看这一期的:云栖说视频.小提示:据说

创业家杂志社负责人谈盛大云实践之路

本文讲的是创业家杂志社负责人谈盛大云实践之路,云计算带来的是服务模式的变革,甚至将引领IT产业的变革,在这种大变革的背景之下,众多有实力的企业纷纷投身云计算领域,谋求新的发展空间.盛大作为互联网服务的领导者,不仅在内容端深受用户欢迎,同时发力云计算服务,推出八大产品系列,给用户提供了一站式的服务. 当然任何的产品和服务都离不开用户的信赖和支持,作为盛大云平台的核心用户之一,创业家杂志是一个实践者,同时也是云服务的受益者.IT168记者专访了创业家杂志和i黑马网联合发起人龙真,从用户那里获得了盛大