单例模式场景模拟和问题解决

饿汉式单例

java 复制代码
private static Student student = new Student();

不存在线程安全问题

懒汉式单例

线程安全问题

java 复制代码
package org.example.Singleton;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class SingletonTest {
    private static Student student = new Student();

    private static Car car = null;

    private static AtomicInteger count = new AtomicInteger(0);

    private static ExecutorService threadPoolExecutor = Executors.newCachedThreadPool();

    private static final CountDownLatch latch = new CountDownLatch(15);

    SingletonTest() throws InterruptedException {
        threadNonSafeLoad();
    }

    public static void main(String[] args) throws InterruptedException {
        loadInstance();
        latch.await();
        System.out.println(count.get());
    }

    private static void threadSafeLoad() {

    }

    private void threadNonSafeLoad() {
        //        System.out.println(this.car);
        if (this.car == null) {
            count.addAndGet(1);
            this.car = new Car();
        }
        latch.countDown();
    }

    private static void loadInstance() {
        for (int i = 0; i < 15; i++) {
//            Thread.sleep(50);
            Thread thread = new Thread(() -> {
                try {
                    new SingletonTest();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            threadPoolExecutor.execute(thread);
        }
    }
}

class Student {
    private String name;
}

class Car {
    private String name;
}

运行结果:

java 复制代码
会多次创建`Car`对象
1~15

解决方法-双重判断

java 复制代码
    private void threadSafeLoad() {
        if (this.car == null) {
            // 避免每次都加锁进行判断
            synchronized (SingletonTest.class) {
                if (this.car == null) {
                    count.addAndGet(1);
                    this.car = new Car();
                }
            }
        }
        latch.countDown();
    }
java 复制代码
    SingletonTest() throws InterruptedException {
//        threadNonSafeLoad();
        threadSafeLoad();
    }

运行结果:

java 复制代码
1
相关推荐
雪的季节7 分钟前
1 个网络线程 + 3 个数据处理线程(完全隔离)
开发语言
weixin_408099678 分钟前
2026 AI生成图片快速去水印的5种实测方法(附在线工具 + Python/Java/PHP API代码)
java·人工智能·python·api接口·ai去水印·石榴智能·自动去水印
风筝在晴天搁浅8 分钟前
快手 CodeTop LeetCode 227.基本计算器Ⅱ
java·开发语言
JAVA面经实录91711 分钟前
RabbitMQ全套学习知识手册
java·rabbitmq
0xDevNull13 分钟前
Java实战面试题(一)
java·开发语言
好家伙VCC14 分钟前
动态因子图谱+滚动SHAP重构量化模型可解释性
java·人工智能·重构
椰椰椰耶17 分钟前
[SpringCloud][11] Nacos 负载均衡,服务下线、权重配置、同集群优先访问
java·spring cloud·负载均衡
Miss roro17 分钟前
通用OA能不能替代专业法务系统?钉钉飞书和律杏法务云的实测对比
java·钉钉·飞书·法律科技·企业诉讼管理·法务管理系统
不是光头 强18 分钟前
feign-list-param-crash-cpp
java·数据结构·list
Chase_______21 分钟前
【Java基础 | 10】异常处理入门:Throwable、try-catch-finally 与异常调用栈一次讲清
java