饿汉式
class LazyMan{
private LazyMan(){};
private static LazyMan lazyMan = new LazyMan();
public static LazyMan getLazyMan(){
return lazyMan;
}
}
懒汉式
class LazyMan{
private LazyMan(){};
private static LazyMan lazyMan;
public static LazyMan getLazyMan(){
if(lazyMan==null)
return new LazyMan();
}
}
但是上面的写法还是不安全的,因为反射的存在。那么就需要双重检测锁,同时对象需要添加volatile关键词确保对他的操作是原子性的。
为什么需要这样做是因为指令重排的存在,实例化操作实际上是三步,分配内存,指向空间,实例化,然而这三步的顺序不是一成不变的,可能是1,2,3,也可能是3,1,2。那么两个线程的操作就会出现问题了,需要volatile防止指令重排。代码如下:
class LazyMan {
private LazyMan() {};
private static volatile LazyMan lazyMan;
public static LazyMan getLazyMan() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
}