写单例模式 双重检查
import java.util.*;
Class Singleton{
// 构造器
private Singleton(){
}
// 创建对象
private static volatile Singleton singleton;
public static Singleton getSingleton(){
if(singleton==null){
synchronized(Singleton.class){
if(singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
常考问题
为什么要有私有构造器
默认有一个无参构造器,防止直接通过无参构造器new一个对象
为什么用volatile修饰
- 保证可见性
- 防止指令重排
为什么用volatile详解
因为new对象的时候其实可以分为以下三步:
a.获取对象地址;
b.在对象地址上初始化一个Factory对象;
c.将factory引用指向对象地址;
如果a->b->c的顺序,并发情况是不会出现问题的
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author flora.zxf
* @date 2021/8/16
*/
public class Singleton {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
//System.out.println(Singleton1.getSingleton1(1L));
// System.out.println(Singleton1.getSingleton1(2L));
if(Singleton1.getSingleton1(11L)==null){
System.out.println(11L);
}
if(Singleton1.getSingleton1(12L)==null){
System.out.println(11L);
}
}
}).start();
}
}
}
class Singleton1{
private Singleton1(){
}
private static volatile Map<Long,Singleton1> map = new ConcurrentHashMap<>();
private static volatile Singleton1 singleton1;
public static Singleton1 getSingleton1(Long userId){
if (map.get(userId)==null) {
synchronized (Singleton1.class) {
if (map.get(userId) == null) {
map.put(userId, new Singleton1());
}
}
}
return map.get(userId);
}
}