文章目录
单例模式
懒汉模式
java
/***
* 单例 懒汉模式
* 使用的时候再创建实例
* 线程不安全
*/
public class LazeSingle {
private static LazeSingle lazeSingle;
public LazeSingle() {
}
public static LazeSingle getLazeSingle() {
if (lazeSingle == null) {
lazeSingle = new LazeSingle();
}
return lazeSingle;
}
}
饿汉模式
java
/***
* 饿汉模式 线程安全
* 加载的时候就实例化了
*/
public class HungrySingle {
private static HungrySingle hungrySingle = new HungrySingle();
public static HungrySingle getHungrySingle(){
return hungrySingle;
}
}
双重锁校验的单例模式
为什么要做双重锁校验
代码中 假设两个线程 都通过了第一判空 阻塞在synchronized锁上 其中一个获取锁成功 另外一个阻塞,
此时 第一个创建了新的对象返回 如果没有第二次判空校验 那么 第二个会在第一个释放锁以后 重新创建对象 这就是有问题的 此时如果有判空的话 可以避免此场景
java
/***
* 双重锁校验的单例模式 线程安全
*/
public class DoubleLockSingle {
private static volatile DoubleLockSingle doubleLockSingle;
public DoubleLockSingle() {
}
public static DoubleLockSingle getDoubleLockSingle() {
if (doubleLockSingle == null) {
synchronized (DoubleLockSingle.class) {
if (doubleLockSingle == null) {
doubleLockSingle = new DoubleLockSingle();
}
}
}
return doubleLockSingle;
}
}
枚举单例
- 线程安全:枚举单例模式在创建实例时自动处理线程同步问题,因此您无需担心多线程环境下的竞争条件。
- 序列化安全:枚举单例模式在序列化和反序列化过程中保持单例特性。这意味着,当您将单例对象序列化到磁盘并再次读取时,您将获得相同的实例。
- 简洁性:与其他单例模式实现相比,枚举单例模式更简洁,易于理解。您只需创建一个枚举类型,并将实例定义为枚举常量。
java
public enum SingleEnum {
INSTANCE;
private final Object obj;
SingleEnum() {
this.obj = new Object();
}
public Object getString() {
return obj;
}
}
public static void main(String[] args) {
SingleEnum instance = SingleEnum.INSTANCE;
SingleEnum instance2 = SingleEnum.INSTANCE;
System.out.println(instance);
System.out.println(instance2);
System.out.println(instance.getString());
System.out.println(instance2.getString());
}
/* 打印结果
INSTANCE
INSTANCE
java.lang.Object@707f7052
java.lang.Object@707f7052 */
单例模式在实际开发中的应用
作为配置类存在。
一般配置只能有一份。
作为缓存存在。
比如要在内存里记录一些东西。可能使用饿汉模式直接存储。
线程池。
使用双重锁校验模式,创建线程池。