欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

DCL锁双重检查;

时间:2023-07-02

学习来源于:B站马士兵视频:《计算机底层原理》

DCL:Double check lock。

其本质是为了解决多线程中语句执行不确定性。

你也不知道当前其他线程进行到哪里,哪里都有可能。

比如在单例模式中,需要判断单例对象是否已经存在,if如果单例存在:则返回单例。否则else就去new一个单例。

这样做有一个问题:当涉及到多线程时,可能有多个线程同时来判断单例是否存在,此时,有两个甚至多个线程同时判断为不存在,则多个线程都会去创建单例。这样还是很多对象。

如何避免,首先考虑加锁,即判断单例是否存在的这个操作,应该加到锁中,判断加锁这个操作,本身也要加锁。

即我们:

S1:先判断单例是否存在,(第一次check)

S2:如果不存在,那我们就要加锁,准备执行创建对象这个过程。

S3:加锁完成后。注意:此时有可能有多个线程,同时判断check发现单例不存在,那么这个锁一旦解开,其他线程还是会进入锁区重新创建对象,所以,需要在锁区,进行第二次check判断单例对象是否存在。这个在锁定代码区中先进性的二次判断单例是否存在,就叫做:DCL。

S4:在锁区内部,第二次check之后,判断单例是否已经存在,如果存在,那么就直接返回,否则创建。

总结:

就是Check-Lock-Check。


此时可能有新的疑问:第一次检查不要可以吗?

不可以:为了避免不必要的锁。假设有一万线程,然后有一个线程抢到了,那么锁释放后,后面其他9999个线程要挨个锁一遍,然后检查单例对象是否存在,然后再出锁。这个一进一检查再一出,是不必要的麻烦。

有了外面这个锁,那么一旦有一个线程new了之后,其他9999个线程,就不用再费劲了。



这样DCL之后就结束了吗?

还没有,CPU执行代码语句是逐条指令执行的。

我们看起来是一条语句,但是在CPU中却是很多条指令。

这个单单的一条语句: new obj = new object();

这条语句在CPU中可以分为以下几条指令完成:其中每一步都有可能被其他线程抢断。

 第一条new:在内存堆中开辟空间。

这个空间的大小取决于T,里面的内容在一开始初始化的时候,不同的语言(C/C++、Java/C#)等,处理方式不同。马老师说Java会给相应类型的默认值。重新赋值:就像分配了一片新的土地。这个土地初始里面种了什么东西,不用的语言处理方式不同。Java会像耕地一遍,重新犁一遍。所以Java的初始化会比C/C++要稍微慢一点。因为多了一个重新赋类型默认值的过程,这样也稍微安全了一点。有利有弊。第二条:dup,马老师未讲。第三条:一开始是变量默认值为0。默认值是new时候的值,代码中初始化为8,初始化在第三步执行。特殊调用T的init初始化方法,就是默认的构造方法。第四条:变量t是一个指针,要通过t能访问到这块堆空间。所以要把这个对象的地址赋值给t。第五条:完成。

以上概括起来:三板斧:一个小小的对象初始化就要:有三步来实现:

首先分配空间:new(),然后赋予成员属性默认值。(类型的default值。)调用构造方法:T.,然后赋予成员属性初始值。(构造函数中指定或者传入的值。)建立关联:指针变量t指向对象所在的内存空间。 

这里涉及另外一个问题:不仅仅程序执行的时候顺序不确定。指令执行时,也有指令重排的问题。

 上锁的代码和不上锁的代码能不能形成并发?能。

所以新的一个线程可以基于目前thread1的线程进度访问到成员属性的状态。即:当指令执行到重排的第二条:7 astore_1时,此时锁中的线程实现了对m = 0的赋值。外界线程可以读到当前单例半实例化状态。

锁定的代码只能保证:

1、原子性。2、可见性。保证原子性更新完之后才可以对另外一段上锁代码可见最终状态。

唯一不能保证的就是线程的有序性。所以锁的代码内部依然可能发生换顺序。

基于上面来看:好像什么代码的执行顺序都可以改变的样子?什么样的顺序不可以换?

判断能不能换,主要一个原则:只要保障 单线程内 数据最终一致性。

比如:a = 0;b = 0;这两条指令哪个先执行,数据最终都一致,所以这两条指令顺序可以发生重排。再比如:x = 0;x = 5;这两条指令:不可以交换顺序。因为数据最终不一致了。上面指令,最终结果都是成员属性m = 8;所以顺序不影响结果。可以交换。


只要保障了线程最终数据一致性就可以交换顺序。

程序优化有两个级别:编译器级别的优化;CPU级别的优化。

无知者无畏:达可效应——丁宁克鲁格效应:越是啥都不会的,胆子越大。马老师希望大家走出自己的愚昧之谷,走上求知之路。



Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。