设计之美【3】单例模式

设计之美【3】单例模式



单例模式是什么?

Java中单例(Singleton)模式是一种广泛应用的设计模式。作用是保证在Java程序中,某各类只有一个实例存在(管理器、控制器等)。


单例模式的要求?

单例模式中通常需要至少三部分构成。

  1. 构造函数
  2. 创建的单例类实例
  3. 调用该实例的方法

其中,构造函数我们必须保证是private修饰的,这保证了其他类是不能够实例化该类的。(唯一的创建方式)。
2和3保证了调用者可以通过我们定义的方法调用该单例对象。这个方法需要时被public和static修饰的,作为类方法,可以通过类名.方法名()的方式调用。


单例模式的具体实现?

通常,我们常用的单例模式包括两类,饿汉模式和懒汉模式,但除此之外我们也可以通过静态内部类或者枚举的方式实现单例模式。

饿汉模式

public class Singleton{
	private static Singleton instance=new Singleton();
	private Singleton(){
		//构造方法
	}
	public static Singleton getInstance(){
		return instance;
	}
}

饿汉模式非常的简洁,谈一下它的优劣势吧。
优势:
饿汉模式能够保证该类只在类加载的时候创建一次,存在于程序的整个生命周期中,不会被多线程的程序创建多个实例。
劣势:
即便没有被用到也会被创建,一定程度上浪费了内存。


懒汉模式及其改进(双检锁机制)

懒汉模式的出现是为了改进饿汉模式的问题的,针对饿汉模式的劣势,饿汉模式做了轻微的修正。主要是两点

  1. 类加载时未实例化
  2. 调用时才创建实例
public class Singleton{
	private static Singleton instance = null;
	private Singleton(){
		//构造方法
	}
	public static Singleton getInstance(){
		instance=new Singleton();
		return instance;
	}
}

优势:按需创建
劣势:在多线程环境下可能创建多个实例
针对懒汉模式的劣势,我们又进行了一定的改进,引入双检锁机制,通过两次判断保证实例的唯一性。

public class Singleton{
	private static volatile Singleton instance=null;
	private Singleton(){
		//构造函数
	}
	public static Singleton getInstance(){
		if(instance==null){//判断是否未被实例化
			Synchronized(Singleton.class){
				if(instance==null){//防止多线程情况下有多个线程进入了第一个判断
					instance=new Singleton();
				}
			}
		}
		return instance;
	}
}

双检锁机制对懒汉模式的改进主要有两处,
第一处是对声明变量instance的地方加了volatile关键字,禁止指令重排序的优化。
第二处是对getInstance方法进行了基于双检锁机制的改写。
针对双检锁机制,
第一个if是确定instance未被实例化时才会调用同步代码块(因为Synchronized性能低,如果已经被实例化的话就不进入该代码块)。
第二个if防止多个线程同时(先后)通过了if判断而未进入同步代码块(第一个线程未被赋值之前就有另一个线程进入了if语句块内),如果不加这个判断的话,如果有多个线程进入if语句块,当当前线程结束synchronized语句块后会继续进行实例化操作,会产生多个实例。


静态内部类实现单例模式

public class Singleton{
	private static class SingletonInner{
		public static Singleton instance=new Singleton();
	}
	private Singleton(){
		//构造函数
	}
	public static Singleton getInstance(){
		return SingletonInner.instance;
	}
}
如果应用中没有使用该内部类,那么JVM就不会加载这个单例类,也就不会创建这个对象,从而达到和懒汉式相同的延迟加载的效果。

枚举实现单例模式

enum singleton{
	INSTANCE;
	private String string;
	public String getString(){
		return string;
	}
	public void setString(String str){
		this.string=str;
	}
}

单元素的枚举类型是实现Singleton的一种方式,枚举类本身提供了序列化机制。


总结

单例模式在编程过程中的应用是相当广泛的,掌握它的写作模式能够有效的帮助理解它的作用。


以上属个人拙见,如有谬误,敬请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值