[设计模式]单例模式(懒汉式和饿汉式)
2017-11-20 19:10
211 查看
单例模式(Singleton pattern)
定义:
一种常见的软件设计模式
目的:
应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
了解了定义和目的后我们先来看一下两种单例模式:
1.懒汉式(lazy):
概念:
顾名思义,通俗的讲,懒汉式就是比较懒的方法,只有当别人调用它的时候,它才去创建这个实例。
代码示例:
class LSingle{
priva
4000
te static Instance_instance = null;
private LSingle(){}
public static Instance getInstance(){
if(_instance==null){
_instance = new Instance();
}
}
分析:
首先创建了一个名为LSingle的类,类里面有一个私密的静态成员对象和私密的构造方法,我们在这里主要看那个静态成员对象(Instance_instance),不难看出在类里并没有实例化它,而是在下面的公开的静态方法里做了一个判断,如果_instance==null,才去创建这个对象,这样其他类在调用这个公开的静态方法时,就会先做判断,只有当它==null的时候,才会去创建,这确实保证一个实例的目的。
优点:
使用懒加载(就是懒汉式),速度是比较快的(相对于饿汉式来讲),因为它不需要在类加载的时候就创建对象。
缺点:
在多线程情况下,不能保证一个实例(只创建一次对象),举例,线程A和线程B同时进入了if(_instance==null),线程A和线程B都满足创建条件,故创建了两个实例,虽然用同步锁可以解决,但是效率很低下。
解决多线程下不是一个单例对象问题:
代码改造:
class LSingle{
private static Instance_instance = null;
private LSingle(){}
//创建一个锁对象
public static Object lock = new Object();
public static Instance getInstance(){
if(_instance==null){
//同步锁,保证同时只能有一个线程进入到这里
synchronized(lock){
//再次判断是否为null
if(_instance==null){
_instance = new Instance();
}
}
}
}
2.饿汉式(Hungry)
概念:
饿汉式恰巧与懒汉式相反,听名字也可以猜个一二,饿汉式,比较饿嘛,所以它在这个对象加载的时候就已经把实例给你创建好了,等待你使用
代码示例:
class ESingle{
private static Instance_instance = new Instance;//注意区别,直接作为成员对象创建
private ESingle(){}
public static Instance getInstance(){
return _instance;//直接返回之前已经创建好的实例
}
}
分析:
首先创建了一个名为ESingle的类,单例对象直接作为类的私密静态成员来创建,下面提供了一个公开的静态方法,返回的是之前创建好的实例对象。
优点:
使用饿汉式可以保证多线程下一个实例的目的(也就是单例),因为即使多个线程同时进入这个方法,返回的也只是一个实例对象,(注意:是多个线程进入到这个方法,而不是这个类),而这个对象在加载时(new时),就已经创建完毕了,所以不会出现懒汉式的那种情况
缺点:
由于单例对象是在类加载的时候完成的,所以比较耗费资源(与懒汉式相比较)
定义:
一种常见的软件设计模式
目的:
应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
了解了定义和目的后我们先来看一下两种单例模式:
1.懒汉式(lazy):
概念:
顾名思义,通俗的讲,懒汉式就是比较懒的方法,只有当别人调用它的时候,它才去创建这个实例。
代码示例:
class LSingle{
priva
4000
te static Instance_instance = null;
private LSingle(){}
public static Instance getInstance(){
if(_instance==null){
_instance = new Instance();
}
}
分析:
首先创建了一个名为LSingle的类,类里面有一个私密的静态成员对象和私密的构造方法,我们在这里主要看那个静态成员对象(Instance_instance),不难看出在类里并没有实例化它,而是在下面的公开的静态方法里做了一个判断,如果_instance==null,才去创建这个对象,这样其他类在调用这个公开的静态方法时,就会先做判断,只有当它==null的时候,才会去创建,这确实保证一个实例的目的。
优点:
使用懒加载(就是懒汉式),速度是比较快的(相对于饿汉式来讲),因为它不需要在类加载的时候就创建对象。
缺点:
在多线程情况下,不能保证一个实例(只创建一次对象),举例,线程A和线程B同时进入了if(_instance==null),线程A和线程B都满足创建条件,故创建了两个实例,虽然用同步锁可以解决,但是效率很低下。
解决多线程下不是一个单例对象问题:
代码改造:
class LSingle{
private static Instance_instance = null;
private LSingle(){}
//创建一个锁对象
public static Object lock = new Object();
public static Instance getInstance(){
if(_instance==null){
//同步锁,保证同时只能有一个线程进入到这里
synchronized(lock){
//再次判断是否为null
if(_instance==null){
_instance = new Instance();
}
}
}
}
2.饿汉式(Hungry)
概念:
饿汉式恰巧与懒汉式相反,听名字也可以猜个一二,饿汉式,比较饿嘛,所以它在这个对象加载的时候就已经把实例给你创建好了,等待你使用
代码示例:
class ESingle{
private static Instance_instance = new Instance;//注意区别,直接作为成员对象创建
private ESingle(){}
public static Instance getInstance(){
return _instance;//直接返回之前已经创建好的实例
}
}
分析:
首先创建了一个名为ESingle的类,单例对象直接作为类的私密静态成员来创建,下面提供了一个公开的静态方法,返回的是之前创建好的实例对象。
优点:
使用饿汉式可以保证多线程下一个实例的目的(也就是单例),因为即使多个线程同时进入这个方法,返回的也只是一个实例对象,(注意:是多个线程进入到这个方法,而不是这个类),而这个对象在加载时(new时),就已经创建完毕了,所以不会出现懒汉式的那种情况
缺点:
由于单例对象是在类加载的时候完成的,所以比较耗费资源(与懒汉式相比较)
相关文章推荐
- iOS学习笔记10-设计模式-单例模式(懒汉式,饿汉式)
- 单例模式中的饿汉式和懒汉式(Java设计模式)
- 设计模式------单例模式之饿汉式和懒汉式
- 单例设计模式-懒汉式和饿汉式
- 设计模式--单例模式(一)懒汉式和饿汉式
- Java单例设计模式(饿汉式和懒汉式)
- 单例设计模式(懒汉式,饿汉式,枚举式,双重检测锁式,静态内部类式)
- 单例设计模式中懒汉式和饿汉式
- java单例设计模式-饿汉式与懒汉式
- 设计模式--单例模式(一)懒汉式和饿汉式
- 设计模式--单例模式(一)懒汉式和饿汉式
- 单例设计模式(懒汉式,饿汉式,枚举式,双重检测锁式,静态内部类式)
- 设计模式中饿汉式单例类和懒汉式单例类
- java单例设计模式 饿汉式 懒汉式
- 单例设计模式(饿汉式和懒汉式)
- 单例设计模式(懒汉式,饿汉式,枚举式,双重检测锁式,静态内部类式)
- (GOF23设计模式)_单例模式_应用场景_饿汉式_懒汉式
- JAVA单例设计模式(饿汉式和懒汉式的区别)
- Java设计模式——单例模式(饿汉式、懒汉式)
- Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式