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


    饿汉式单例

    private static Student student = new Student();
    

    不存在线程安全问题

    懒汉式单例

    线程安全问题

    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;
    }
    

    运行结果:

    会多次创建`Car`对象
    1~15
    

    解决方法-双重判断

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

    运行结果:

    1
    
  • 相关阅读:
    leetcode每天5题-Day54(贪心3)
    Mojo语言的运用
    听GPT 讲Rust源代码--library/core/src(7)
    C++重载操作符
    httpserver 下载服务器demo 以及libevent版本的 httpserver
    SpringSecurity - 自定义过滤器使用 Json 格式登录
    JVM学习(宋红康)之运行时数据区之虚拟机栈中方法返回地址
    Java基础-反射(3)
    记一次 .NET 某金融企业 WPF 程序卡死分析
    FFmpeg入门及编译
  • 原文地址:https://blog.csdn.net/weixin_43349479/article/details/140372982