23种设计模式——单例模式
饿汉式
先创建对象,要使用的使用直接拿
package com.mjh.single;
public class Hungry {
//可能会浪费
private byte[] da=new byte[1024*1024];
private byte[] da1=new byte[1024*1024];
private byte[] da2=new byte[1024*1024];
private byte[] da3=new byte[1024*1024];
private Hungry(){}
private final static Hungry HUNGRY=new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}
懒汉式
1)简单式(单线程)
public class LazyMan {
private LazyMan(){}
private static LazyMan lazyMan;
public static LazyMan getInstance(){
if (lazyMan == null) {
lazyMan = new LazyMan();
}
return lazyMan;
}
2)在多线程并发下,双重检测
懒汉模式在多线程并发下有一定的问题,所以我们要加双重检测锁;在这一过程中 lazyMan = new LazyMan();并不是一个原子性,会出现指令重排现象(打乱了存储的顺序),对于这种情况还要加上volatile
package com.mjh.single;
public class LazyMan {
private LazyMan(){}
private volatile static LazyMan lazyMan;
//双重检测锁模式的 懒汉式单利 DCL懒汉式
public static LazyMan getInstance(){
if(lazyMan==null){
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();//不是一个原子性操作
/**
* 1.分配内存空间
* 2.执行构造方法,初始化对象
* 3.把这个对象指向这个空间
*
* 123
* 132 A 没有问题
* 突然来了 B//此时LazyMan还没有完成构造 就会默认为lazyMan不等于null,直接返回
* 为了避免指令重排,必须加上 volatile
*/
}
}
}
return lazyMan;//此时lazyMan还没有完成构造
}
}
3)静态内部类的懒汉模式
package com.mjh.single;
import com.sun.org.apache.bcel.internal.classfile.InnerClass;
public class Holder {
private Holder(){}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER = new Holder();
}
}