单例设计模式--java实现

单例设计模式是一种常见的软件设计模式,通过这种模式,可以保证系统中,该类只有一个实例对象。

对于系统中的某些类来说,只有一个实例很重要,比如一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务。为了保证一个类只有一个实例对象,需要满足以下三个条件:

    1、外界无法创建该类对象,所以该类对象的构造函数是私有的,外界无法使用。

    2、既然外界无法创建该类对象,并且要保证该类只有一个实例对象,就需要在类中创建实例对象。

    3、为整个系统提供这个实例,所以创建一个public函数向外提供该类的实例对象。

Java 中常见的设计模式很多,单例设计模式是最简单的一种。有很多实现方式,其中懒汉式、饿汉式、静态内部类较为常见,并且后两种的实现更为优秀。

代码:

/*
懒汉式
原理:延迟加载,通过同步机制保证多线程安全,当需要创建的时候才会创建
优势:使用两个if提高效率,同步机制保证多线程安全
缺点:代码复杂,容易出错,由于使用了同步机制,效率低
*/
class Single1{
	//构造函数私有
	private Single1(){

	}

	//私有静态单例实例对象,初始化为null
	private static Single1 s = null;

	public static Single1 getInstance(){
		if(s == null){
			synchronized(Single1.class){
				if(s == null)
					s = new Single1();
			}
		}

		return s;
	}
}

/*
饿汉式
原理:在单例类中定义了私有静态的单例对象,当单例类加载到内存中时,就创建了该单例类,通过public函数返回该单例对象
优势:代码简洁,容易实现。
缺点:由于类一加载进内存,就创建了单例实例对象,可能过早地创建了实例,降低了内存的使用效率
*/
class Single2{
	//由于外界不能创建该类对象,所以该类的构造函数是私有的
	private Single2(){

	}

	//私有静态的单例实例对象,该类加载到内存就创建了该实例对象
	private static Single2 s = new Single2();

	//共有函数返回单例实例对象
	public static Single2 getInstance(){
		return s;
	}
}

/*
静态内部类
原理:在单例类中定义一个私有的静态内部类,内部类中定义了一个私有静态的单例实例对象,当外部类加载到内存时,内部类不会被加载到内存,只有用到的时候才会加载到内存。这样就可以保证不会过早地创建实例对象,提高了内存使用效率。
优势:不会过早地创建实例对象,而是在需要创建的时候才会创建,提高了内存的使用效率。
*/
class Single3{
	//外界不能创建该类对象,所以构造函数是私有的
	private Single3(){

	}

	/*
	 * 定义静态内部类,内部类中定义私有静态的单例实例对象,外界无法访问该内部类,所以该内部类是私有的,是静态的。如果内部类不是static,那么其中的变量s也不是static,那么getInstance函数中就必须创建该内部类对象来获取实例对象,那么就无法保证实例对象的唯一性,所以内部类是是static的,并且其中的变量s也是static的,如果不是静态的,那么在getInstance函数中,也需要创建内部类对象才能获取变量,无法保证实例对象的唯一性,所以都是static的。为了让外界无法访问该内部类,需要是private
	 */
	private static class Inner{
		private static Single3 s = new Single3();
	}

	//公有函数,返回该类的实例对象
	//只有调用该函数,才会把Inner加载到内存中,提高内存的使用效率
	public static Single3 getInstance(){
		return Inner.s;
	}
}

class SingleDemo{
	public static void main(String[] args){
		//在栈中创建两个变量,指向堆内存中的Single1实例对象,如果是单例设计模式,那么只有一个单例对象,所以s11和s12指向同一个对象,所以s11==s12,返回true
		Single1 s11 = Single1.getInstance();
		Single1 s12 = Single1.getInstance();
		System.out.println("s11 == s12  "+(s11==s12));

		Single2 s21 = Single2.getInstance();
		Single2 s22 = Single2.getInstance();
		System.out.println("s21 == s22  "+(s21==s22));

		Single3 s31 = Single3.getInstance();
		Single3 s32 = Single3.getInstance();
		System.out.println("s31 == s32  "+(s31==s32));
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值