单例模式:懒汉模式与饿汉模式

单例模式

1、概述
单例模式是23种设计模式之一,也是最常用的设计模式。
就是系统运行期间,有且仅有一个实例。

例:

package cn.smbms.utils;
/**
 * 单例类
 * @author 14062
 *
 */
public class Singleton {

	//私有静态成员
	private static Singleton singleton;
	
	//私有构造
	private Singleton(){}	
	
	//向外界提供获取实例的静态方法
	public static Singleton getInstance(){
		if(singleton==null){
			singleton=new Singleton();
		}
		return singleton;
	}
}

解: 必须满足单例模式的三个关键点:

  • 一个类只能有一个实例(只能提供私有构造器,即保证不能随意创建该类的实例)
  • 它必须自行创建这个实例。要保证唯一性,也就意味必须创建一个实例,那么就需要该类自行创建,以便向外界提供该类实例时使用。
  • 它必须自行向整个系统提供这个实例。外界需要获取并使用这个单例类的实例,但是由于该类的构造器是私有的,外界无法通过new去获取它的实例,那么就必须提供一个静态的公有方法,该方法创建或者获取它本身私有对象并返回。

2、懒汉模式

概述:即在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例。上面一段代码即为“懒汉模式”,此种方式虽然保持了其延迟加载的特性,但存在安全问题,在多线程下无法正常工作。如果需要解决线程安全的问题,最简单的方式就是使用synchronized关键字实现同步。
例:

	//向外界提供获取实例的静态方法
	public static synchronized Singleton getInstance(){
		if(singleton==null){
			singleton=new Singleton();
		}
		return singleton;
	}

注: synchronized锁住的是类对象。懒汉模式虽然保留了延迟加载特性,但存在线程安全问题,所以使用synchronized关键字实现同步,但此种方式会降低效率,不推荐使用。

3、饿汉模式
概述:指在类加载的时候就完成了初始化操作,故类加载较慢,但是获取对象的速度很快,并且由于饿汉模式在类初始化时就已经自行实例化,因此不存在线程安全问题。
例:

	//直接实例化
	private static Singleton singleton=new Singleton();
	
	//私有构造
	private Singleton(){}	
	
	//向外界提供获取实例的静态方法
	public static Singleton getInstance(){
		return singleton;
	}

注: 静态方法getInstance()直接返回已经自行实例化好的对象,这种方式基于classloader机制,有效的避免了多线程的同步问题。但是也有可能会有其他的地方(或者其他静态方法) 导致类装载,而此时单例类Singleton在类装载时就实例化,显然没有达到lazy loading的效果。在实际开发应用中,可能既需要lazy loading的效果,在效率与安全方面又有保证,这就需要用静态内部类来解决问题。

4、静态内部类

package cn.smbms.tools;
/**
 * 单例类demo
 * @author 14062
 *
 */
public class Singleton {

	private static Singleton singleton;
	private Singleton(){
		//在整个应用运行期间,只执行一次的业务操作代码(如读取配置文件的操作)
	}
	
	//静态内部类
	public static class SingletonHelper{
		private static final Singleton INSTANCE=new Singleton();	
	}
	
	/*
	 * 只有通过调用getInstance()方法时,才会主动调用SingletonHelper类,
	 * 并完成对SingletonHelper的加载,从而实例化Singleton,达到lazy loading的效果。
	 */
	public static Singleton getInstance(){
		singleton=SingletonHelper.INSTANCE;
		return singleton;
	}

	public static Singleton test(){
		return singleton;
	}		
}

5、小结

  • 懒汉模式:类加载时不创建实例,因此类加载速度快,但是运行时获取对象的速度较慢,具备延迟加载的特性,但是存在线程不安全的问题。

  • 饿汉模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象速度快。

  • 静态内部类:即在单例类内部定义静态内部类,在静态内部类中完成对象的实例化操作,只有主动调用静态内部类时才会初始化实例,从而保证了线程的安全并达到延迟加载的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值