1. 饿汉模式 -线程安全
在类加载时进行实例化, 线程安全,但会导致类加载时间变长。饿汉模式如果使用过多,可能会对App启动耗时带来不利影响。
2. 懒汉模式 -线程不安全
没有加锁, 因此线程不安全。
3. 两次判空 + 加同步锁 -线程不安全
instance为null时加锁,不为null时不加锁,效率有提升,但由于android编译优化,有可能类未完成构造函数的调用, 就已经将instance指向了分配的地址空间,进而根据instance是否为空判断是否加锁不可靠,导致线程不安全。
注意, 这里加的是synchronized(Singleton.class)字节码锁, 因为class对象在工程启动后是唯一的。
4. volatile关键字+两次判空 + 加同步锁 -线程安全
volatile关键字的作用是, 禁止指令重排序,保证多线程时每次访问该变量时, 都从主内存中更新该变量在本线程中的本地副本。
volatile关键字+两次判空 +加同步锁才是懒汉模式实现单例的正确写法。通过加volatile关键字解决了android代码优化导致的指令重排问题,确保每次判空都是有效的。同时通过字节码锁,保证判空逻辑和对象创建过程不被其他线程抢占,进而实现线程安全。