单例模式的意义
1.当想控制实例数目,节省系统资源的时候。
2.解决如果多个实例会造成冲突、结果不一致问题
确保一个类最多只有一个实例,并提供全局访问。
实现:
将类的构造函数设为私有,和本身的静态实例;并提供了一个静态方法,供外界获取它的静态实例
class Singleton |
static 对象实例 |
private 构造函数 static getInstance() (静态方法,供外界获取) |
优化:
问题:
如果在多线程情况下,两个线程同时new对象。一个线程在判断为空后,再进行new前的同时,另一个进程也将会把对象判断为空。
解决:
1.懒汉式:方法加上synchronized修饰加锁,适合次数较少的实例化
2.饿汉式:“急切”创建实例,定义类静态变量时直接new;如果该类用不到实例,可能会造成浪费资源。
3.双重检查加锁,代码如下:
package SingletonPattern;
/**
* Description:
*
* @author tzw
* CreateTime 16:32 2020/3/10
**/
public class Singleton {
private volatile static Singleton singleton;
/**
* 双重检查加锁法
* @return
*/
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
在A线程判断为空之后,进入同步代码块,此时B线程也判断为空,等待线程A释放锁;A线程创建实例之后释放锁,B线程进入同步代码块,再次判断,此时已经有该对象,故不再次创建。