Android 工具 Utils 单例模式 线程安全 详解

一 . 概要:

单例模式:

A.  一个类只能构建一个对象,自然不能让它随便去做new操作

B.  分为 懒汉模式饿汉模式

C.  考虑到 线程安全

网上看别人写的单例模式很多,多数都没有考虑到线程安全的例子。

在此,总结一下,第三版 是线程安全的。重点讲解 第三版代码。

二. 封装列举

 首先


public class A{
    private A() {}  //私有构造函数
    private static A instance = null;  //单例对象
    //静态工厂方法
    public static A getInstance() {
        if (instance == null) {
            instance = new A();
        }
        return instance;
    }
}

这就是一个单例,但是有不足的地方很多。

第一,这样写 是没有错的。可以运行,也符合,只创建一个对象。确实是单例,这是懒汉式,要想饿汉式,那就开始时候new

private static A instance = new A();  

但是,问题来了,。。。。。要是多线程时候呢,线程A 和 线程B 同时执行到 if(instance) 这个时候,instance是null 都进入 if 语句

那么就有 new 两次,多个对象,显然又不符合单例模式。。。单例单例,就是只有一个。。。那么我们继续往下看第二版本



然后

public class A{
    private A() {}  //私有构造函数
   private static A instance = null;  //单例对象
   //静态工厂方法
   public static A getInstance() {
        if (instance == null) {      //双重检测机制
         synchronized (A.class){  //同步锁
           if (instance == null) {     //双重检测机制
             instance = new A();
               }
            }
         }
        return instance;
    }
}

这个比前面的好一些了,双重检查机制  又判空 null 又加锁,这回多个线程访问是问题的。

可以防止 new A() 执行多次

总体看是可以的,但是还不是绝对线程安全

假如  : 要么Instance还没被线程A构建,线程B执行 if(instance == null)的时候得到true;要么Instance已经被线程A构建完成,线程B执行 if(instance == null)的时候得到false。

真的如此吗?答案是否定的。这里涉及到了JVM编译器的指令重排

指令重排,这个东西有点难讲解,实力不足。。。大神多指点。。。

需要增加 volatile 关键字 线程安全用

最后

public class A{
    private A() {}  //私有构造函数
    private volatile static Ainstance = null;  //单例对象
    //静态工厂方法
    public static A getInstance() {
          if (instance == null) {      //双重检测机制
         synchronized (A.class){  //同步锁
           if (instance == null) {     //双重检测机制
             instance = new A();
                }
             }
          }
          return instance;
      }
}

注意看代码 第三行。第三行。第三行。

这回,线程够安全了,volatile这个字在百度百科

简单地说就是防止编译器对代码进行优化。比如如下程序:

 
 
XBYTE[2]=0x55;
XBYTE[2]=0x56;
XBYTE[2]=0x57;
XBYTE[2]=0x58;
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在 寄存器里的备份。 以上是百度百科的说法。。。 结束,,,,,感谢小灰灰, 让我知道有volatile这个关键字,分享出来,给大家。
 
 



猜你喜欢

转载自blog.csdn.net/qq_33495943/article/details/79034320