饿汉式单例
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