单例模式

75 阅读1分钟
懒汉模式?
  • 私有化构造
  • 静态常量初始化对象,在类加载的时候就创建好实例
  • 不存在线程安全问题
public class SingleMode {
    private static final SingleMode singleMode = new SingleMode();
    private SingleMode(){}
    public SingleMode getInstance(){
        return singleMode;
    }
}
饿汉模式?
  • 私有化构造
  • 静态属性
  • synchronized 获取实例
  • 不存在线程安全问题
public class HungryMode {
    private static HungryMode hungryMode;
    private HungryMode(){}
    public static synchronized HungryMode getInstance(){
        if (hungryMode == null){
            hungryMode = new HungryMode();
        }
        return hungryMode;
    }
}
双重检查?
  • 私有化构造
  • volitile 静态属性
  • 双重检查
  • synchronized
public class DoubleCheckMode {
    private static volatile DoubleCheckMode doubleCheckMode;
    private DoubleCheckMode(){}
    public static DoubleCheckMode getInstance(){
        if (null == doubleCheckMode){
            synchronized (DoubleCheckMode.class){
                if (null == doubleCheckMode){
                    doubleCheckMode = new DoubleCheckMode();
                }
            }
        }
        return doubleCheckMode;
    }
}
为什么双重检查时属性要加volatile?
  • java对象的创建可能发生指令重排序,导致可能拿到半对象结果
第一重检查的目的是?
  • 尽量减少synchronized锁竞争
第二重检查的目的是?
  • 避免多次创建对象
详细说说java对象创建过程 Object o = new Object(),及重排序?
  • NEW java/lang/Object 【申请内存空间,并赋默认值】
  • INVOKESPECIAL java/lang/Object. () 【执行构造方法,并赋初始值】
  • ASTORE 【引用关联】

截屏2024-04-01 22.37.45.png

  • 当 引用关联 和 执行构造赋初始值 重排序时 引发多线程问题
为对象分配内存,具体分配多大?

对象内存计算

  • 对象头 【8byte(hash、GC age、偏向锁 thread id)】
  • classpointer 类指针 【4byte】
  • instance data 【数据】
  • padding 对齐填充【对象大小补齐为8byte的倍数】 比如:Object o = Object(),占用 4 + 8 + 4 = 16byte