博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式的5种写法
阅读量:5329 次
发布时间:2019-06-14

本文共 2569 字,大约阅读时间需要 8 分钟。

单例模式(Singleton Pattern):

在平时的开发中,可能会用到单例模式,许多java的笔试题中也会叫笔试者写出单例模式的那几种写法并且分析。那么下面就来轻轻地探讨一下,最简单的设计模式,即单例模式。

单例模式的解释:

GoF对单例模式的定义:保证一个类只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。说的意思就是一个类在整个程序中就只能有一个实例,并且这个类中要定义一些可以全局访问的属性、方法等。

 

单例模式的要点有三:

1、有且仅有一个实例。 2、自己创建自己的实例。 3、自己向整个应用程序提供这个实例。

 

单例模式的应用场景:

如窗口管理系统、打印缓冲池、文件系统它们都是原型的例子。

单例模式按实例化对象的时间先后可以大体分为两种类型,即饿汉式和懒汉式,接下来将列出5种单例模式的写法,并分析他们缺点。

第一种:饿汉式

 

/** * 单例模式-饿汉式 */public class Singleton {	// 在定义的时候就初始化instance,	private  static Singleton instance = new Singleton();		// 够造函数必须是私有的,不能被外部直接调用。	private Singleton(){	}		// 暴露给外部,提供实例。	public static Singleton getInstance(){		return instance;	}}

缺点:在加载类的时候就实例化了对象,比较浪费资源。

 

第二种:懒汉式(一)

 

/** *  单例模式-懒汉式(一) */public class Singleton {		private  static Singleton instance ;		// 够造函数必须是私有的,不能被外部直接调用。	private Singleton(){	}		// 暴露给外部,提供实例。	public static  Singleton getInstance(){		if(instance == null){			instance = new Singleton();		}		return instance ;	}}

缺点:多线程不安全。比如两个线程同时进入getInstance()发现instance为空,那么它们都会去执行new Singleton(),从而导致实例不止一个。

 

第三种:懒汉式(二)- 方法同步

 

/** *  单例模式-懒汉式(二) */public class Singleton {	private  static Singleton instance ;		// 够造函数必须是私有的,不能被外部直接调用。	private Singleton(){	}		// 暴露给外部,提供实例。	public static synchronized Singleton getInstance(){		if(instance == null){			instance = new Singleton();		}		return instance ;	}}

缺点:对方法进行了同步,解决了多线程访问时的不安全性,但是每次调用getInstance()都会去判断锁的状态,比较耗时。

 

第四种:懒汉式(三)- 双重检查

 

/** *  单例模式-懒汉式(三) */public class Singleton {	private  static Singleton instance ;		// 够造函数必须是私有的,不能被外部直接调用。	private Singleton(){	}		// 暴露给外部,提供实例。	public static Singleton getInstance(){		// 1		if(instance == null){			// 2			synchronized(Singleton.class){				// 3				if(instance == null){					// 4					instance = new Singleton();					// 5				}			}		}		return instance ;	}}

优点:双重检测有效地避免了资源浪费的情况,只有在第一次调用getInstance()方法时才会初始化。

第一个if判断存在的必要性在于提高性能,只有第一次调用getInstance()方法是才会被调用。
第二个if判断存在的必要性在于实现单例,当很多线程在同步块外面等待一个个进入时,如果发现instance不为空了,则不实例化。
缺点:在多线程环境中任然不安全。
例如:多线程的涉入可能会导致instance还没有初始化完成就被当做完整的实例返回给了应用程序了。也就是说线程1正在实例化instance,
线程2运行到//1这个位置发现instance不为空,那么按程序的流程就应该返回instance,但是这个时候的instance还未被实例化完成。

 

第五种:懒汉式(四)- 内部类

 

/** *  单例模式-懒汉式(四) */public class Singleton {	// 够造函数必须是私有的,不能被外部直接调用。	private Singleton(){	}		// 暴露给外部,提供实例。	public static Singleton getInstance(){		return SingletonHolder.instance;	}		// 静态内部内,实现延时加载	private static class SingletonHolder{		public static Singleton instance = new Singleton();	} }

优点:实现了延时加载,也就是说没有在类被加载时就去实例话对象。

 

经过这5种写法各有千秋,都有好有坏,现在大家用双重检查用得比较多,当然我觉得还是懒汉式(四)要好一点,这个跟android里面绑定service很相似,但是仅仅是内部类这一点。

 

转载于:https://www.cnblogs.com/suncoolcat/p/3306343.html

你可能感兴趣的文章
[简讯]phpMyAdmin项目已迁移至GitHub
查看>>
转载 python多重继承C3算法
查看>>
【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)
查看>>
css文本溢出显示省略号
查看>>
git安装和简单配置
查看>>
fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
查看>>
Awesome Adb——一份超全超详细的 ADB 用法大全
查看>>
shell cat 合并文件,合并数据库sql文件
查看>>
Android 将drawable下的图片转换成bitmap、Drawable
查看>>
介绍Win7 win8 上Java环境的配置
查看>>
Linux设置环境变量的方法
查看>>
构建自己的项目管理方案
查看>>
利用pca分析fmri的生理噪声
查看>>
div水平居中且垂直居中
查看>>
epoll使用具体解释(精髓)
查看>>
AndroidArchitecture
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
大数据学习
查看>>
简单工厂模式
查看>>