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