单例模型
1.单例模式的定义
确保一个类只有一个实例,并且可以自行实例化并向整个系统提供这个实例
2.单例模式的特点
- 构造器私有
- 自行构造实例
- 通过共有的静态方法向外提供实例的获取
3.常用的两种单例模式
1. 懒汉式
package com.wxc.singleton.singleton4;
/**
* 懒汉式
*/
public class Singleton {
private static volatile Singleton singleton = null;
private Singleton() {
}
public static Singleton getSingleton() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
2. 饿汉式
package com.wxc.singleton.singleton4;
/**
* 懒汉式
*/
public class Singleton {
private static volatile Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getSingleton() {
return singleton;
}
}
4.存在的问题
懒汉式在多线程环境下存在线程安全问题
5.改进的方案
1. 加锁
在getSingleton方法上加上synchronized或者方法内部加上synchronized。
2.双重检查锁定
package com.wxc.singleton.singleton4;
/**
* 双重检查锁定
*
* 加上volatile的原因:
* 因为在 new Singleton中,其实在JVM内部并不是一个操作,而是分为三步
*
* 1 .memory = allocate(); // 1:分配对象的内存空间
* 2. ctorInstance(memory); // 2:初始化对象
* 3. instance = memory; // 3:设置instance指向刚分配的内存地址 // 注意,此时对象还没有被初始化!
*
* 由于在JIT编译器上可能会出现重排序,导致,2和3的顺序交换,那就会出现instance指向了地址,即instance不为null,
* 但是instance并没有初始化对象,导致有问题,访问对象的方法会报错
*/
public class Singleton {
private static volatile Singleton singleton = null;
private Singleton() {
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}