【7.30】群讨论未完待续。。。
1、为什么要进行两次判空?
1)提效:第一次判断是在Synchronized同步代码块之外进行的,所以,第一次判断是为了在instance对象已经创建的情况下,避免进入同步代码块,提升效率;
2)保证唯一:当两个并发线程访问同一个对象同步代码块时,一段时间内只能有一个线程得到执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块;
举个栗子:有并发执行的线程A和B,假如线程A已经进入了同步代码块并判断instance == null成立,于是开始创建Singleton3Java的实例;此时线程B也来凑热闹了,它判断第一个instance == null成立于是也进入了同步代码块但是由于A线程还没有执行完,所以B被block住了;当A执行完B重新获得执行的机会,这时第二个instance == null不成立,这样就保证了instance的唯一性。
2、构造函数为什么是私有的?
构造函数私有化,是防止外部直接new ,破坏单例模式
3、为什么要加volatile?
1)synchronized 加锁这个也容易理解,就是为了多线程同步了,同一时刻,只有一个线程能进入同步代码快。
2)因为在这种情况下会存在多个并发线程同时进入到getInstance()方法,所以会存在这样的情况:线程A在自己的工作线程内创建了实例,但此时还未同步到主存中;此时线程B在主存中判断instance还是null,那么线程B又将在自己的工作线程中创建一个实例,这样就创建了多个实例,所以这里加入volatile来保证可见性,防止这种情况的出现。
3)保证及时同步,让其他线程保存的对象副本失效。让他再次从主存中重新获取副本。
4、双重检查模式的优缺点?
缺点:代码多,但和双重校验模式来讲代码量又还好;优点:既能保证线程安全与单例的唯一,又能延迟单例的实例化。外部类加载时并不会立即加载内部类,内部类不被加载则不去初始化instance,因此不会占内存。
5、单例模式的应用场景
1)单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,线程池hiexcutor, 数据库historage, activitymanager,shareprefrence…
2)配置类比如课程中的HiLogManager;
工具类:比如AppGlobals;
一些管理类:比如我们课程后面会讲到的Flutter预加载与缓存的管理类HiFlutterCacheManager等。
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星