1.饿汉式:在类初始化时创建
public class SingletonDemo {
private SingletonDemo() {
}
private static SingletonDemo instance = new SingletonDemo();
public static SingletonDemo getInstance(){
return instance;
}
}
2.懒汉式:双重判断加锁
public class SingletonDemo {
private SingletonDemo() {
}
private static SingletonDemo instance = null;
public static SingletonDemo getInstance(){
if(null==instance){
synchronized (SingletonDemo.class) {
if(null==instance){
instance = new SingletonDemo();
}
}
}
return instance;
}
}
这种方式可能会有问题,当一个线程执行到instance = new SingletonDemo();时候,另一个线程获取实例,可能获取到null,
实例化对象分为三步;
1.内存开辟新空间
2.实例化对象
3.对象指向内存地址
在这过程中可能出现重排序,即第2、 3步互换,导致另一个线程获取的实例为null;
解决方式加上volatile关键字:private static volatile SingletonDemo instance = null; 防止重排序
也可以在静态代码块中实例化,这个要注意顺序:
private static SingletonDemo instance = null;
static{
instance = new SingletonDemo();
}
3.枚举方式:
public class SingletonDemo {
private SingletonDemo() {
}
public static SingletonDemo getInstance(){
return Singleton.INSTANCE.getInstance();
}
private enum Singleton{
INSTANCE;
private SingletonDemo instance;
//JVM保证只被调用一次
Singleton(){
instance = new SingletonDemo();
}
public SingletonDemo getInstance(){
return instance;
}
}
}