1. 单例模式
工厂方法模式属于创建型模式
在我们使用一些框架时(比如Mybatis),经常会遇到有些类(比如sqlSessionFactory),这些类在系统 运行的过程中只需要一个实例对象,所以我们一般都是交给spring来管理。这种情况就类似于:我们对于该类的管理中,只允许生成一个对象实例。这时候我们必须对构造方法做出一些改动,因为如果我们不显示改变构造方法,默认的构造方法是public的,这样我们的程序就可以通过new 来实例化多个对象,所以我们完全可以把这个类的构造方法实例化称为私有的,这时候默认的构造方法就失效了。
这时又有一个问题,如果我们把构造器私有化,那么我们就不能够使用使用new 来实例化类,这时候不是一个实例都没有了?其实并不是,这时候只能说对于外部代码不能使用new来实例化,但是private的构造方法可以被类内部的方法调用嘛。但是我们完全可以在类里面写一个静态的public方法叫做getInstance(),方法的目的就是返回一个类的实例。而在这个静态方法中做是否实例化的判断,如果没有实例化过直接调用private的构造方法来new出这个实例。这就是一个很基本的设计模式:单例模式
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
下面用代码来演示这个例子:
package com.Singleton;
public class Singleton {
private static Singleton instance;
//内部私有的构造方法
private Singleton() {
}
//静态方法获取实例
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
客户端 测试代码:
package com.Singleton;
import org.junit.Test;
public class Client {
@Test
public void test1() {
//获取两个实例
Singleton instance1= Singleton.getInstance();
Singleton instance2= Singleton.getInstance();
if(instance1 == instance2)
System.out.println("两个引用指向一个地址,所以是一个实例");
else
System.out.println("两个引用指向不同地址,所以是二个实例");
}
//~~~~output:
//两个引用指向一个地址,所以是一个实例
}
2. 多线程的单例模式
上面的实例是一个单线程的单例模式,如果在多线程的环境中呢?如果多个线程同时(注意是同时)访问Singleton类,调用getInstance方法,这时就会创建多个实例了。
解决办法:这时可以给该方法加一把锁,确保代码处于临界区。