设计模式二单例模式

Posted 月牙儿June

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式二单例模式相关的知识,希望对你有一定的参考价值。

创建一个对象并不难,但当我们不得不为每新添加一种抽象类接口而到处修改客户代码时,就不得不思考直接使用new创建对象带来的高耦合。创建类型的模式将使用对象和 实例化对象 进行了分离。创建类型模式包括:单例模式、工厂方法模式、原型模式。下面先看单例模式:

单例模式:保证一个类在系统里只有一个实例化对象。

应用:缓存池、数据库连接池、线程池、一些应用服务实例。

1.最简单的单例

package jyy.DesignPattern.singleton;

public class Singleton 
	//只有一个构造方法,且被private修饰,客户对象无法创建该类的实例。
	//因为为了限制该类的对象被随意创建,需要保证该类构造方法是私有的,这样外部类就无法访问该类对象了。
	private Singleton() //被private修饰的构造函数
		
	
	
	//other fields...
	
	//为了给客户对象提供该单例对象的访问,设置一个全局访问站点:
	private static Singleton instance=new Singleton();
	public static Singleton getInstance()
		return instance;
	
	
	//other methods

//单例模式提供了静态公有方法,用户使用单例模式的代码很简单:
//Singleton singletion=Singleton.getInstance();

此实现时线程安全的,当多个线程访问getInstance()方法时,不能初始化多个对象,因为JVM在加载此类事,对static修饰的属性只能由一个线程执行,且仅一次。如果该实例需要比较复杂的初始化过程,

2.延迟实例化单例对象

Static属性修饰的东西在加载类时就会被初始化,但是我们希望在第一次用到该类的实例时才去实例化,那么应该怎么办呢?——只需把单例的实例化过程移至getInstance()方法。为了保证线程安全,需要用synchronized关键字修饰,但是这样在多线程高并发访问的情况下,会使性能大不如前。(synchronized修饰的代码块一段时间内只能由一个线程执行,这个线程占据同步锁,其他线程被阻塞,需要等待当前线程执行完成后再执行)。仔细分析会发现这样是没有必要的,因为我们只需要保证实例化这个对象的那段逻辑被一个线程执行就可以了,而返回引用的那段代码是没必要同步的。因此可作如下实现:

package jyy.DesignPattern.singleton;

public class DoubleCheckSingleton 
	private volatile static DoubleCheckSingleton instance=null;//volatile保证线程可见性,当实例被某个线程创建时,能够立马被其他线程看到
	
	private DoubleCheckSingleton();
	
	public static DoubleCheckSingleton getInstance()
		//先判断实例是否已经被创建了,如果还没有创建,首先使用synchronized同步实例化代码块
		if(instance==null) 
			synchronized (DoubleCheckSingleton.class) //synchronized同步实例化
				/**由synchronized声明的代码块称为同步代码块
				 * 二次检查实例是否已经被创建,因为如果是多线程同时进入该方法,都检测到instance为空,不管是哪个线程先占据同步锁,
				 * 并创建实例对象都不会阻止另一个线程继续进入实例化代码块并重新创建新的实例对象,只不过是在一个线程完成之后另一个
				 * 线程再创建。这样还是回产生多个实例对象。因此在同步代码块中,要进行第二次判断实例是否已经被创建。
				 */
				if(instance==null)
					instance=new DoubleCheckSingleton();
				
			
		
		return instance;
	



以上是关于设计模式二单例模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式二单例模式

java设计模式之单例模式

Android框架设计模式——Singleton Method

设计模式比较

单例模式作用特点及常见的单例模式分析(6种单例模式分析)

单例模式的简单分析