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

饿汉式单例

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
相关推荐
yaoxin52112338 分钟前
384. Java IO API - Java 文件复制工具:Copy 示例完整解析
java·开发语言·python
NotFound4861 小时前
实战指南如何实现Java Web 拦截机制:Filter 与 Interceptor 深度分享
java·开发语言·前端
Ava的硅谷新视界2 小时前
用了一天 Claude Opus 4.7,聊几点真实感受
开发语言·后端·编程
rabbit_pro2 小时前
Python调用onnx模型
开发语言·python
一 乐3 小时前
医院挂号|基于springboot + vue医院挂号管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·医院挂号管理系统
浪客川3 小时前
【百例RUST - 010】字符串
开发语言·后端·rust
鱼鳞_3 小时前
Java学习笔记_Day29(异常)
java·笔记·学习
烟锁池塘柳03 小时前
一文讲透 C++ / Java 中方法重载(Overload)与方法重写(Override)在调用时机等方面的区别
java·c++·面向对象
一叶飘零_sweeeet3 小时前
深入拆解 Fork/Join 框架:核心原理、分治模型与参数调优实战
java·并发编程
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【23】短期记忆
java·人工智能·spring