单例模式场景模拟和问题解决
饿汉式单例
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 { 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
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。