00:00
各位同学大家好,接下来为大家介绍第七章volatile与GMM。上一讲我们刚刚完成了我们的Java内存模型,那么紧锣密鼓再接再厉再说一下我们的vla,呃,说起vla呢,我相信大家呢,应该是不陌生,或多或少都见过,或者用过了解过,但是呢,应该是结合我们之前讲的GMM内存模型happen before先行发生规则,对它的底层原理应该呢还没有涉及。说使用很简单。这个是一个普通的实例变量,那我现在为什么要加个。它在高并发下面是经常使用的,你以前没方法里面,由于大部分初学者啊,作为你只有且仅有一个单线程,你这个根本就用不到,所以说在初学者的眼里面看来,这个是一个很陌生的知识,但是你是一个高并发的程序啊,这个是你必须要了解的,OK,那么来跳来吧,我们来看看。首先,拜拜莱太修饰的变量,它有两大特点。
01:01
第一个。是可见性,第二个是有序,诶前面我们说GMM规范的时候,同学们我们讲过几可见原子有序,但是为什么我这儿只写了两个呢?非常抱歉,VE变量不支持原子性。它只满足。GMM规范下面的两个可见和有序,而且它这个有序我们前面呢也介绍过第一个。在结果一致,结果正确的前提下,为了程序跑得更好更快,是允许你去做指令重排的,哎,就比如说123,你可以执行132 OK,你自己去优化,那么下面有编译器的优化,内存的优化,指令的优化,你从源代码到最后的结果。和是顺序有可能是不一样的,但是加了外的太阳,它呢。说明这个变量有排序要求,它呢是什么?有时候需要你进重排,哎一也就是说你现在加了贝尔特的变量,不允许你重排了,你要听我的顺序,可以这么讲,我觉得现在不能交给编译器这样的自动档。
02:16
人工手动挡,我来告诉你该不该重排,我自己要把这个决策权收回来,由程序员自己决定,所以说我们V的内存语义,它呢主要呢是有这么几个内容。第一个。当写一个标量变量的时候,GMM会把该线程对应的本地内存中的共享变量的值怎么着立即刷新回主内存当中。前面我们说过在GM规范下,多线程对内存的读取,那么有一个东西叫主内存是共享变量存放的,每个线程自己人手一份,有一个私域的空间是我自己的。
03:01
拷贝过来的变量副本所工作的工作,各人各自的工作空间,那么当我们啊,假设对这个age修饰这个A去写操作的时候,注意写的时候,那么写完以后立刻会把。这个本地内存中就是线程自己修改的,共享变量的这个值立刻刷新回主内存中,就是写完以后线程A里面的立刻刷新为主内存,告诉大家我修改了最新结果听我的,那这个是不是可见?第二个。当读一个变量的时候,GMM会把该线程对应的本地内存设置为什么无效,重新回到主内存中读取最新的共享变量?那说白了,多个线程协作A修改完了,它是外的啊,假设是外修饰的一个变量,这个是前提条件,写完了立刻刷新回主内存。那么大家在读这个变量的时候,比方说B,可能我还正在读着,突然收到消息,不好意思啊,你手头上这一份不香了,它作废,请你立刻重新回到主内存中读取最新的共享变量,因为已经有人动过了,他把最新的版本刷到了主内存当中,请你立刻去拿最新版,你手头上这个就失效了。
04:20
OK,所以VE的写内容语义是直接刷新回到主内存当中,V的读内存语义是直接从主内存当中读最新的,哎,所以说这个就是外laile的什么内存的含义,那么外laile凭什么可以保证这个可见和有序呢?你加个关键词啊就能。保障大家。立刻写,立刻写操作立刻刷新回去读操作立刻去读最新的第二个,你凭什么可以进重排呢?那么来底子就是靠一个东东,俗称内存屏占,哎,这个100%是面试中的高频重点,可以这么讲。
05:01
完了,他要考你两个点,第一个。可见和进程排第二个,说一下底层原理,维莱太尔它为什么能保证这些东西啊,那么靠的就是内存屏障好,这是面试的重点,我们下一讲给大家专题开讲。
我来说两句