理解设计模式之单例模式

  |   0 评论   |   0 浏览

什么是单例

  之前文章里面写过设计模式总结,里面有一类设计模式,叫创建模式,也就是说用来规范类对象的创建的,单例模式就是创建模式其中的一种。我们知道Java创建对象,通过new关键字来创建的话,new一次就会新创建一个与之对应的对象,也就是在JVM堆中会分配内存空间给这个对象使用(Java内存模型这块,可以参考周志明写的《深入理解Java虚拟机》)。如果new的对象过多,一是对象占用内存多,二是影响GC效率,严重的甚至会影响应用程序响应速度(跟GC有关)。如果说一个对象是无状态的,也就是说这个对象本身的属性,经过对象初始化过后,在以后各个线程中执行时候,是不会被修改的,那么这个对象就是无状态的,像这种无状态的对象,没有必要每次线程调用都去new一个对象,因为对象内部没有随业务变化的属性,因此是需要new一个这样的对象就行了,后期多线程访问就只需要访问这一个对象的属性即可。像这种情况,我们需要控制这个类的实例生成,保证整个JVM堆中只有1个此类的对象,这种设计模式就叫单例模式,单例意思就是单实例,英文叫SingleTon。

常用的单例模式

  这里虽然叫单例模式,但是实现的方式有很多种,看过网上的资料,可能叫法有很多,什么懒汉式、饿汉式,但是常用的我只做简单说明,也不取名,懂意思就行。
  1、静态属性直接初始化对象,静态方法中直接返回此对象,适合简单对象的初始化,如下所示:

public class A{
   private static final A instance=new A();
   private A(){}
   public static A instance(){
	  return instance;
   }
}

  2、复杂一点的对象,单例模式的初始化,一般采用双重校验方式,如下所示:

public class A {
	private String field1;

	private static A instance;

	private A() {
	}

	public static A instance() {
		if (instance == null) {
			synchronized (A.class) {
				if (instance == null) {   //第二次校验,防止多线程操作导致对象覆盖
					instance=new A();
					instance.setField1("SingleTon"); //初始化对象属性
				}
			}
		}
		return instance;
	}

	public String getField1() {
		return field1;
	}

	public void setField1(String field1) {
		this.field1 = field1;
	}

	......
}

  在整个开发过程中,可能使用第二种的情况会比较多,是需要记住的代码方式。

Spring

  上面是通过手动写单例模式,不过Spring框架已经为我们提供了单例的容器,Spring的Bean注入管理,默认就是单例的。当然可以通过修改Scope来修改单例或者是原型模式,这个可以百度一下具体了解。

  我们在整个使用设计模式的过程中,一定要明白为什么要使用这种模式,而不是只记住它的代码是怎么写的。


标题:理解设计模式之单例模式
作者:michael
地址:https://blog.junxworks.cn/articles/2018/09/29/1538201901647.html