Java单例模式
2021-04-14 本文已影响0人
arrow_zh
单例的5中方式
1、懒汉式
缺点:线程不安全
/**
* 懒汉式
* 缺点:线程不安全的
*/
static class LazyClass {
private static LazyClass lazyClass = null;
private LazyClass (){}
public static LazyClass getInstance(){
if(lazyClass == null) {
lazyClass = new LazyClass();
}
return lazyClass;
}
}
2、懒汉式变种(双重检查加锁)
/**
* 懒汉式变种
* 注意此处的变量必须加volatile修饰 如果不加volatile可能造成线程不安全
* 主要原因是英文 doubleCheckClass = new DoubleCheckClass() 不是原子操作
* 其中分为三步,第一步开辟内存空间,第二步初始化对象, 第三步赋值引用,其中在高并发场景下可能发生指重排
* 双重检查加锁
*/
static class DoubleCheckClass {
private static volatile DoubleCheckClass doubleCheckClass = null;
private DoubleCheckClass(){}
public static DoubleCheckClass getInstance(){
if(doubleCheckClass == null) {
synchronized (DoubleCheckClass.class) {
doubleCheckClass = new DoubleCheckClass();
}
}
return doubleCheckClass;
}
}
3、饿汉式
/**
*饿汉式
*缺点:一上来就初始化空间,不是用也要占用内存空间
*/
static class HungryClass {
private static HungryClasshungryClass= new HungryClass();
private HungryClass(){}
public static HungryClass getInstance(){
returnhungryClass;
}
}
4、静态内部类方式
/**
* 静态内部类方式实现
*/
static class InnerClass {
private static class InnerClassHolder {
/**
* 静态类初始化 JVM来保证线程安全
*/
private static InnerClass innerClass = new InnerClass();
}
private InnerClass(){}
public static InnerClass getInstance(){
return InnerClassHolder.innerClass;
}
}
5、枚举
/**
*枚举方式实现单例
*/
static enum EnumClass {
instance;
}
破坏单例的三种方式
1、反射
解决方案:定义一个全局变量,当第二次创建时候就抛出异常
2、克隆
解决方案:重写clone方法,直接返回当前单例对象
3、序列化
解决防范:添加readResolve() 返回单例对象
/**
* 破坏单例的几种方式
* 1、反射
* 2、克隆
* 3、序列化
*
* 解决方法
* 1、反射
* 定义一个全局变量,当第二次创建的时候抛出异常
* 2、克隆
* 重写clone(),直接返回单例对象
* 3、序列化
* 添加readResolve(),返回Object对象
*/
static class Singleton implements Serializable,Cloneable{
private static volatile boolean isCreate = false;//默认是第一次创建
/**
* 1.构造方法私有化,外部不能new
*/
private Singleton() {
if(isCreate) {
throw new RuntimeException("已然被实例化一次,不能在实例化");
}
isCreate = true;
}
//2.本类内部创建对象实例
private static volatile Singleton instance;
//3.提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return instance;
}
/**
* 防止序列化破环
* @return
*/
private Object readResolve() {
return instance;
}
}