================================
©Copyright 蕃薯耀 2022-05-20
一、饿汉模式
public class Hunger {
/**
* 增加final关键字,避免被修改
*/
private static final Hunger hunger = new Hunger();
/**
* 私有化,避免创建对象
*/
private Hunger() {};
/**
* 提供获取对象的方法
* @return
*/
public static Hunger get() {
return hunger;
}
}
二、饿汉模式(静态块)
可以通过配置文件对实例进行初始化
import lqy.utils.PropertiesUtils;
public class HungerStatic {
private static final HungerStatic hungerStatic;
private String name;
/**
* 私有化,避免创建对象
*/
private HungerStatic(String name) {
this.name = name;
};
static {
String name = PropertiesUtils.readKeyValue("config.properties", "name");
hungerStatic = new HungerStatic(name);
}
/**
* 提供获取对象的方法
* @return
*/
public static HungerStatic get() {
//System.out.println(hungerStatic);
return hungerStatic;
}
/*
@Override
public String toString() {
return "HungerStatic [name=" + name + "]";
}
*/
}
三、懒汉模式 - 同步方法
public class LazySafe {
private static LazySafe lazySafe;
private LazySafe() {}
public static synchronized LazySafe get() {
if(lazySafe == null) {
lazySafe = new LazySafe();
}
return lazySafe;
}
}
四、懒汉模式 - 同步块
public class LazySync {
/**
* 需要加volatile防止指令重排
*/
private static volatile LazySync lazySync;
private LazySync() {}
public static LazySync get() {
synchronized (LazySync.class) {
if(lazySync == null) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
lazySync = new LazySync();
}
}
return lazySync;
}
}
五、懒汉模式 - 双重判断
public class LazySyncDouble {
/**
* 需要加volatile防止指令重排
*/
private static volatile LazySyncDouble lazySyncDouble;
private LazySyncDouble() {}
public static LazySyncDouble get() {
if(lazySyncDouble == null) {
synchronized (LazySyncDouble.class) {
if(lazySyncDouble == null) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
lazySyncDouble = new LazySyncDouble();
}
}
}
return lazySyncDouble;
}
}
六、懒汉模式 - 内部类
/**
* Inner是一个内部静态类,当外部类 LazyInner 被加载的时候,并不会创建 Inner实例对象。
* 只有当调用 get() 方法时,Inner才会被加载,这个时候才会创建 instance。
* instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。
* 所以,这种实现方法既保证了线程安全,又能做到延迟加载。
* @author islee
*
*/
public class LazyInner {
private LazyInner() {}
/**
* 静态内部类
*
*/
private static class Inner{
private static final LazyInner lazyInner = new LazyInner();
}
public static LazyInner get() {
return Inner.lazyInner;
}
}
七、枚举【最安全方式】
最安全,能预防反射和反序列化的安全问题
/**
* Java虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次。
* [最安全],其他的会存在反射和反序列化的安全问题
*
*/
public class SingletonEnum {
private SingletonEnum() {}
private enum SingletonHolder {
INSTANCE;
private final SingletonEnum singletonEnum;
private SingletonHolder() {
singletonEnum = new SingletonEnum();
}
private SingletonEnum get() {
return singletonEnum;
}
}
public static SingletonEnum get() {
return SingletonHolder.INSTANCE.get();
}
}
测试:
import lqy.design.singleton.SingletonEnum;
public class SingletonEnumTest {
public static void singletonEnum() {
long startTime = System.currentTimeMillis();
for(int i=0; i<15; i++){
new Thread(()-> {
System.out.println(SingletonEnum.get());
}).start();
}
long endTime = System.currentTimeMillis();
System.out.println("耗时:" + (endTime - startTime));
}
public static void main(String[] args) {
singletonEnum();
}
}
(时间宝贵,分享不易,捐赠回馈,^_^)
================================
©Copyright 蕃薯耀 2022-05-20