单例模式
1. 懒汉模式
public class LazySingleton {
public static void main(String[] args) {
}
}
class Singleton{
private Singleton singleton;
private Singleton() {
}
public Singleton getSingleton(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
上面就是典型的懒汉模式单例
但是问题就是这样会有线程安全问题 如果我开了两个线程,全部走到了null判断那里,这样会new出两个。解决办法就是
public Singleton getSingleton(){
if(singleton==null){
synchronized (this){
if(singleton==null)
singleton=new Singleton();
}
}
return singleton;
}
这样就会是线程安全的 ,而且当多个线程走到了加锁的位置,下面还会有一个if的判断,就能保证线程安全。但是问题是在java运行过程中,编译jit(编译)或者cpu 会有三个步骤: 分配空间,初始化,赋值 。但是这个过程中会出现指令重排的问题,先赋值再初始化,或者先初始化在赋值。如果经过了先初始化在排序,多线程情况下会出现空指针异常。解决方案就是
private volatile Singleton singleton;
volatile是在内存可见,可以让对应内存空间不会发成重排序。
2.饿汉模式就不说了,就是static
3.静态内部类,也是懒汉。在调用时候才会加载内部类。