单例设计模式深究
饿汉式:
/**
* @ClassName EHanShi
* @Description 单例 ===》饿汉式
* :造成资源浪费
* @Author 86188
* @DAte 2022/3/8
**/
public class EHanShi {
private static EHanShi eHanShi = new EHanShi ();
public EHanShi () {
}
public static EHanShi getInstance(){
return eHanShi;
}
}
懒汉式:
/**
* @ClassName EHanShi
* @Description 单例 ===》饿汉式
* :造成资源浪费
* @Author 86188
* @DAte 2022/3/8
**/
public class EHanShi {
private static EHanShi eHanShi = new EHanShi ();
public EHanShi () {
}
public static EHanShi getInstance(){
return eHanShi;
}
}
当在单线程模式下: 结果是可行的:
但是在多线程的形况下:
//多线程
public static void main ( String[] args ) {
// System.out.println (LanMan.getInstance ()==LanMan.getInstance ());
for (int i = 0 ; i < 10 ; i++) {
new Thread (()->{
LanMan.getInstance ();
},String.valueOf (i)).start ();
}
}
结果:(创建了多个对象 不符合单例)
总结:饿汉式 早早创建资源 ,线程安全
懒汉式 线程不安全
懒汉式线程不安全解决:(DCL双重检锁 + volatile )
当然可以加 sychronzied 关键字保证线程安全!当然也有别的方法(DCL:double check Lock 双重检索机制)!!!!
public static LanMan getInstance()
{
//双重检锁
if (lanMan == null) {
synchronized (LanMan.class){
if (lanMan == null) {
lanMan = new LanMan (); //不是原子性,可能发生指令重排
/*
* 1.创建空间
* 2.初始化对象
* 3.指向空间
* */
}
}
}
return lanMan;
}
结果:
但是 DCL 不一定是安全的!! 会发生指令重排!加volatile后可以禁止指令重牌!
private static volatile LanMan lanMan = null;
最终版懒汉式:
public class LanMan {
private static volatile LanMan lanMan = null;
private LanMan(){
System.out.println (Thread.currentThread ().getName ()+"创建了对象");
}
public static LanMan getInstance()
{
//双重检锁
if (lanMan == null) {
synchronized (LanMan.class){
if (lanMan == null) {
lanMan = new LanMan (); //不是原子性,可能发生指令重排
/*
* 1.创建空间
* 2.初始化对象
* 3.指向空间
* */
}
}
}
return lanMan;
}