00:00
好,那么同学们。介绍完了GMM。它是一种抽象的内存计算模型,它并不真实存在啊。再次强调,并不真实存在,只是一种规范和约束。类似于我们十二生肖属龙,它不存在,但是我们中国人的传统文化,只要一说你是属龙的,大家是不是都懂啊?好,就好比我说你是属羊的,你不会跟我说你是山羊呢,还是绵羊,还是属喜羊羊。反正一句话就是阳好,那么这种是我们大家约定俗称的一种规范,那么。接下来那。这个线程它的GMM。有三大特性,GMM。可见。原则。有序,注意啊,GMM是大多数多线程开发需要遵守的规范,也即可见原则有序,但是注意我们的volatile。为什么说它清亮呢?可见性。
01:00
GM规定要你支持啊。完了支持,可见对可见这一步OK,但是注意GMM要求你保证原子性,那抱歉,那我完了太干嘛不保证原子性。哪个保站SYNCH的。第三步要保证有序性,那么呢,干嘛?完了tell禁止指令重排,我不让你重排,不让你插队,它是不是叫有序?那么所以说GGM多线程编程的三大特性,完了它基本上能保证两个,最坑爹的就是它不保证原子性那么好。所以说GMM的三大特性就是可见原子有序。那么好,由于可见性是GMM规定的。第二,Valla也保证。所以说。这些接下这一讲,接下来我们就要给大家论证什么叫volatile的可见性,那么当然这个可见性它是不是也就是GMM的可见性?好,那么兄弟们跟着杨哥来。
02:00
那么第二板斧第一板斧学习杨哥讲过永远三板斧理论代码小总结。好,那么现在我们反过来说。小总结,就这句话。杨哥已经给你正确答案和理论了拉。tell是Java虚拟机的轻量级的同步机制,它基本上遵守了GMM的规范,主要是什么?可见性和有序,禁止指令重排,但是他并不保证原子性好,你第一问回答正确,面试官马上会说,那你写个DEMO给我证明一下什么叫保证了可见性。来,兄弟们再次强调,刚才从画图到这儿,杨哥说过,这个内存模型,第一个主物理内存,第二个什么各个县城各自的什么东东工作内存。第三步。你在工作内,你从主内存拷贝,大家都一样,只要有任何一个线程计算完了,他要把自己工作空间的写回给主内存。但是还要让。
03:05
其他线程能够第一时间看到,这种第一时间就能看到的现象就叫什么可见性,OK,说白了就是及时通知。好,那么同学们开工,咱们代码说话,先来给我证明可见性。兄弟们请看。In number现在等于零,初始值,同学们没问题。现在public void。ADD。60。啥意思啊,二话不说。this.number等于60,也就是说我现在干什么呢?只要后面有一个线程,调这个方法将会把这个值从零推到60,言下值是这个指数是出现了变动。好,那么这个时候呢,干什么呢?就有点类似于我们现在画的这张图,主物理内存,我是不是要一个my date。
04:08
默认的初始值number,它有一个什么东东?共享变量number是等于零。现在某一个线程A,它调用了这个方法,已经把这个A。线程做的作为就是把这个my date共享变量里面的值干嘛。写完了以后刷新回主内存是不是从零改为了60,那么我要求另外的一个线程,比方说这个是B是main线程,它要能够收到,这么说能跟上同学们。好,那么不废话,我相信这个方法同学们很简单吧。我这没有加private,也不想写set get,直接兑现,可以点取,这样我是不是可以少写点代码,我就偷个了,重要的不是写那些set get那么好,那么第一个。验证。File。的可见性。那么我们怎么验证?
05:04
第一步。假如。Number等于零。Number变量。之前。根本没有添加。Volatile。关键字修饰。对不对,同学们,这个是不是就是最简单的一个普通变量。好兄弟们,接下来按照严格的要求,是不是线程套动资源类?来资源类M值是什么?妹是。一切方法的。运行助考。它只是起道从这走好吧,那么现在。线程操纵资源类。MY等于六。
06:00
My data OK,这是我们的是吗?线程要操纵。资源类好兄弟们。看好。现在。尿thread前面讲过,这个是一个实现了runable接口的拉的表达式,这个就是我们这的。AAA线程,同学们,这一步没问题吧?好,那么现在是言下之意就是线程AAA要操纵这个资源类MY,你干嘛呢?那么首先。我们呢?开工,那么呢?点current name这句话的意思是不是AAA线程?好,那么呢?Come in。好,那我come in干什么呢,注意。线程操作资源类一进来了,说明我要修改,可能我要做这件事,要做这么几秒钟听懂我干嘛呢。
07:04
MY。好,那么这个时候干嘛呢?我肯定要运算一下对吧,运算一下以后我们这儿呢。直接干嘛,停三秒钟能理解故意的,那么呢?好,言下之意就是只要A线程进来,说明我要准备开始超到number变量的变值了,听懂。但是需要有点时间,那么这个时间呢,大概是三秒钟,OK,那么注意这三秒钟,别的线程是不是也已经读取这个变量了。好,那么这个时候请看三秒钟以后我干,我会干一件什么事呢?这个时候my date点。ADD to60,同学们能跟上,也就是说,三秒钟以后,我将把这个值改为60。同学们这一步听不听得到?那么接下来干嘛呢?
08:01
现在这个线程是不是就AAA线程了。进来画了三秒钟,把值从零改为60,对不对?那么现在这个就是A线程。Update。Number value,那么同学们懂得,如果一切顺利,那么三秒钟以后,MY他自己改了以后,他自己知不知道,他肯定知道,那么说明什么概念,我这个MY的值。是不是已经从零变更为60,同不同意?好,但是注意同学们。这是我们的第一个线程AAA,我们的现在的第二个线程。就是我们的may线程,这么说能跟上三秒钟以后,这个值才会被从才会从零改为60,同不同意,但是。一开始进来main线程读到的值是不是就应该是初始值零啊,那么所以说内线程干嘛呢?我要。
09:00
只要my date的值number等等零,那么这个时候干嘛?我这个main线程就一直在这里等待。循环。直到。什么呢?Number值。不在。等于零,这么说能跟上。好,如果说一切顺利,MYT,那么这块注意现在能到第40行了,这一行的这个名字可就是内线城,是另外一个线程了,这一波能跟上。那么干嘛呢?Mission is over,任务完成,言下之意就说,如果这个只要失离我,那我妹线程只能在这绕着死循环,对不对?这句话我根本打不出来,那么这句话要是打出来,说明我没线成感知到了这个number已经从零变为了60啊,我的可见性。
10:05
被触发听懂,好,那么同学们,我们现在不妨来验证一下我们的这个东东。现在我们先。整体讲一遍。第一个。Number等于零。这个时候number变量之前根本没有添加关键字,也就是什么的。没有。可见性。也就是说一个线程现在AAA。花了三秒钟以后,将已经将number从零改为60了。内线成他妈,他根本就不知道。它只是一开始的值是零,我是不是读到这个初始值啊,傻傻的,我就在这转着。我根本就不知道,没有人通知我。某个线程已经把我们my date里面的这个共同值number已经变为了60,我三秒钟以后。
11:02
AAA已经将它改为60了,但是内线程根本就不知道。没有可见性,所以可见性是一种及时通知机制啊。那么这个时候同学们请看。我们一运行。A come,三秒钟以后修改,请看三秒钟以后AAA update number8,六值是不是已经从零变为60了?但是抱歉。Look。什么概念?根本就没有停,也就是说这一块在idea里面它是不是一直转着。三秒钟以后A线程。三秒钟以后,A线场已经把什么呢?自己的。工作空间的这个值零已经改为了60啊,并写回了主物理内存,我们懂的,我们读的是不是都是同一个对象?叫my date,尽量语法高亮显示是不都是同一个对象?
12:01
但是现在在第30行是AAA线程操纵,在第三十五行这个my date现在是main线程卡在这儿,A线程已经把my date从零。变为60了。也就是说,我已经把这个值写回主物理内存,这是60了,但是不好意思啊,根本对内线程不可见,没有任何人来通知内线程,说主物理内存的最新值已经从零变为了60。所以说A线程。现在改完以后。我们的,嗯,第二个线程,我们的内线程。干嘛还在这傻傻的等着我,是不是一直以为我这个值还是零啊?但实际真实情况是什么?这个值啊,已经是60了,那说明已经不等于零了,但没有人通知我,所以说魅线程依旧在这儿安静的坐着一个美男子。没人。找我报告,没人通知我,其他线程对这个变量的修改对我而言是不可见。
13:05
听懂了吗?好,所以说我们现在修改程序自动关闭,来兄弟们。很好。神奇的现象发生了。我们呢,直接。Volatile。听着vallatile就是增强了。主内存和各线程之间的可见性,只要有一个线程改了主物理内存的值,其他线程马上收到通知,迅速获得最新值,听懂,那么这个时候请看,那么呢,Mission is over,那么这个时候干什么呢?我们再加一个may get number value。这个时候是不是也是我们的my date.number同学们能不能跟上?好,请看。第一种情况,刚才见了那A线程,确实把它从零改为60了,我改了,但是没人通知内线程。
14:03
对不对。注意。我们可没有加同步啊。这个就是一个最普通的方法。那么接下来我们的内线程。需要被通知。然后直至程序走到第40行结束,否则我一直在这就转着,好,同学们,请跟着我来。此时。我们加了V,我们直接我点。A进来三秒钟改为60。请看。AAA是60了,May线程任务完成没有卡死在那,没有在那死循环,就三秒钟以后,May get number value60啊,请问AAA线程,Main线程这两个线程的值现在是不是都是60啊?这就叫什么,只要有一个线程修改了主物理内存的值,马上刷新,回去的时候,只要是加了完了关键词的变量,其他线程迅速收到最新通知,你的修改对,我们可见,我知道你改为最新值了,前值作废,现在我们马上马上拿到主物理内存的最新值,这个就是vla的可见性的证明。
15:16
这一步能跟上。好。第一板斧看了。刚才的笔记理论第二板斧,我们是不是用代码case证明了最后同学们不浮躁?一步步来,我们不是教大家背题,杨哥要教大家是切切实实掌握深刻的知识,请各位同学思考A线程。B线程就是may把刚才的case和这段笔记请再读一下,尤其注意变量的副本拷贝和写灰主物理内存。好。那么这大家请看现在。第一遍读不能读懂,回答,我通过我的讲解,代码案例演示,再来第二遍读,我感觉比第一遍应该有提升了吧。
16:07
那么注意。我们刚才强调的这个缓存。基本上就是这个GMM内存模型的一种硬件抽象。再说白一点,各种CPU跟内存,它把那个值这个GMM就有点类似于刚才我们那个软件。三级缓存,OK,那么它的一种抽象机制,那么就是我们这所说的并不真实存在,好,那么各位同学这个就是什么我们GMM和volatile的什么可见性的一种综合统一的验证。
我来说两句