00:00
好,那各位同学,接下来我们先看vla的可见性的特征以及底层原理的讲解。那么在研究vla要讲清楚之前,我们接下来先要研究一个新的知识。G。MM。这题。还没讲完。怎么,老师,杨哥你怎么又扯出来一个新的知识点GMM啦?那么这个时候请。按照老师的要求来进行学习。听好。去年甚至前年1718年基本上一道必考的题目是GVM,那么这个时候听到这个是Java虚拟机,那只要是Java程序,地球人都知道。但是最近这一两年。由于这道GVM的题目,比方说一言不合让你画一张GVM的图,大家都背过学过了,那么用人单位他没有办法挑出最好的Java工程师,所以说题目升级,尤其现在非常注重你在上一家当前这家公司做的是高并发系统还是单机版的系统。
01:08
那么如果是高并发的系统,自然而然问题频出,为了解决这些问题,你不得不去研究底层,一研究底层,自然而然会来一个东东叫GM。这个东东。注意,它不是Java虚拟机,它是Java。内存模型。现在基本上大厂都会跟你聊聊GMM,如果你说不知道,那没办法,一定没干过高并发,一定没有用过GOUC这样的多线程编程,你也就是传说中的增删改查程序啊,你那个业务也就这么回事。不是找不到工作,而是你很难突破18000、2万,甚至是两万五以上。那么现在我们就要来唠唠什么叫Java内存模型,它跟我们的VE有什么关系?首先这道题是请你谈谈velaile的理解。好,那么回到这儿。我们首先对于GMM,我们有一个。
02:03
深度的解析。第一个。GM内存模型Java memory是一种抽象的概念,干嘛并不真实存在?它描述的是一种规范、规矩、约束和约定。这种习惯有点类似于什么呢?那。同学们都明白,中国有十二生肖属相。都有一个属相叫属龙的。你给我动物园,动物园里面给我牵一条出来看看。这个龙就像是一组十二生肖里面的一个档位,一个规范,一个约定,通过这组规范定义的程序中各个变量,包括实例、字段、静态等等的一种什么东东访问方式,那么关于GMM,关于同步的规定。线程解锁之前,必须把共享变量的值刷新回主内存,怎么又来个概念叫主内存了,那么这儿不要着急,我们呢刷到一个概念,老师呢给你讲解一个概念。
03:05
好,那么再来。线程加锁前必须读取主内存,最新的只到自己的工作内存。怎么又来个内存就内存,不就一条内存条吗?怎么又叫自己的工作内存了呢?那不要着急。杨哥逐渐给大家讲解清楚。加锁解锁,同意吧。好,那么这块我们先来看这么一个问题,然后这一小段话要求同学们先囫囵吞枣。读完一遍,我们再开讲,给大家30秒钟。好,那读完的同学呢?我敢保证,班上大部分同学肯定是。不敢说,一脸懵逼,也是满脸半脸懵逼,反正吧,他们都是中文。也理解,理解不了,吃透不了全部的意思,但是你要说一点不懂啊,感觉好像能摸到点边,那么这个时候看着大家半脸懵逼的状态,那别读了。
04:08
读一遍老师的要求学三遍干嘛呢?这遍读完了,那我就告诉你,假设这就是一本书,我会向大家证明为什么你现在。干嘛必须跟着杨哥学,为什么你自己什么自学,想看看书,想成为高手,这个是不可能的,没有老师就带你,你不开挂,那基本上你的成长有限。抬高。首先。读完的同学,不管懂得多少,别读了,我们开高。我们要先解决GM内存模型。好,那么首先我们大家都会明白。对于我们工作当中数据的传递和存储,它的速率基本上是这样,那就是什么呢?硬盘。干嘛呢?是不是弱于我们的?
05:02
内存。不用多讲,我们的买车Q数据库装在硬盘上,OK。但是数据存储以后,要大规模的存取了以后,我们都明白,磁盘硬件有个东西绕不开,叫IO,它是纯硬件上,它有它的什么上限限设置和限制,达到了一定的阈值以后,它很难再突破,除非硬件上有突破。好。但是我们的数据不会因为说你存在硬盘上,它就饶了你,尤其在现在大数据时代,要求数据的读写、存储都得很快,那么最终我们明白了一个问题。部分数据咱们别存在买CQ了,也就说别放在硬盘上。发内存里面你看都是一个硬件对应着一个软件,那这个内存什么鬼?那么大家之前杨哥给大家讲过,是不是叫分布式的内存数据库red,那么大家都明白内存的读取数据是不是一定要快过于硬盘好,那么接下来那比内存更快的呢?那么这个时候过来,那么就是我们的什么CPU。
06:05
那么这个是什么概念,那你说那我懂了啊,那从内存里面存到CPU里面不错啊,不是啊,CPU是管计算不管存储啊。那么这个时候我们干嘛呢?但是我们会出现这么一个情况,假设CPU比内存快,那么在这个中间。这段时间。读取速度,CPU的计算能力超强,算完了但是数据还运不上来,那怎么办呢?或者我CPU算完了以后。我还没传给内存呢,那我CPU就这一直耗着,那不行,那么这个时候干嘛?我们一定要明白,在CPU和内存读取的存储之间还有一点空间,那么这个空间也就是我们的什么鬼。CPU和内存之间的。缓存。那么这个时候干嘛呢?我们从硬件上来说。那么大家。可以看老师这儿的CPU。
07:02
拿出这个软件。稍等哈。我给他。重新启动一下啊。我们重新共享一下屏幕,接下来同学们请看这个CPU老师呢已经启动,那么这个时候CPUZZ看CPU的。这个时候请看。杨哥的笔记本四核八线程,注意,这有个什么鬼。缓存。那么来大家看一级,二级、三级,那么这个时候说白了什么?如果CPU的速度要大于内存,这是肯定的,那么在这个速率上面,如果CPU比内存坏,CPU一直闲着,那么这个时候干嘛?是不是导致我们的性能会下降?干错一部分,计算的数据已经算好了。我们先把它存在这些缓存里面,那么这个时候我们可以抽象的理解为是这么一种情况。
08:04
首先,我们的数据占内存。每位同学现在在你们的内存插槽里面也都有一条内存条,也就是我们平时所做什么?比方说你的内存八个G,这个是不是就是我们插在主板上的一种。硬件没问题吧,兄弟们这个时候注意。这种硬件干嘛呢?就俗称我们的主内存。那么言下之意。我们的这个。就叫主内存,也就是我们平时所说的,你买一台电脑内存多少,你是8G的内存还是16G的内存,那再说白点,也就说我们new一个student这么一个实例对象,我们都明白是不是在内存里面在哪了,就在这个里面,这一步从硬件上来说,同学们能不能跟上。第二步。那么现在。
09:02
这个主内存,比方说我们现在有一个student。对象他的年龄,假设我们现在是25岁,那么这个时候由于我溜出来的这份。干嘛?所有的引用是不是都指向它,那么这个时候干嘛我们在物理内存,物理内存里面这个值尤其仅有一份。好,接下来到了高并发的时代,多个县城就跟我们卖票一样,假设我们都要改他的年龄,可不可以三个县城来改这个年龄?完全可以三个售票员卖30张票,三个售票员来改这个25的年龄,只不过一个数是30张票,一个是不是年龄是25,那么这个时候,但是呢。我们这个时候再缓存这。出来了。由于CPU太快。那么这个时候过来。部分存储就在这儿,那么干什么呢?来。这是线程一。
10:02
这是县城二。这是线程三,那么这个时候老师为了给大家区分好。这个叫G1。这个叫T2。那么这个呢,我们呢,把它称为T3。好,现在三个线程都要操,操作25号。操作age是25的这个数字,那他怎么玩的呢?是不是每一个线程都去改这个对象呢?不对。这么干?首先,每一个线程都将会把主内存里面的这份25拷贝回自己线程一份。那么这种东东干什么,就是俗称什么。各自现成的工作内存。也就是我们这儿所说的自己的工作内存。
11:02
这句话。也就是说,假设在多线程里面,我在内存里面。有一个25这个值我要去改,我不是直接去改主物理内存这个通告,而是形成一种什么。县城。一种变量的拷贝。也就是说,实现了变量。拷贝,将这25各自拷回各自线程的工作内存里面,那么也就是说现在就变成第一站。有一个。25、这么说,同学们听不听得懂,那么再来。我现在呢,T2这有个25,我这呢,T3这有一个25 OK,那么接下来。各自拿走。相当于。主路里内存这一份儿不动。各自县城从主物力内存那有一份拷贝和快照,自己带回自己家里面,这么说OK。
12:04
然后进一线程要加25。修改为。多少呢?新的值。37。好,我已经改完了。但是注意线程之间,我根本没有办法横向。我并T2和T3并不知道,我改成37了,我也不知道你的运算效果以后,现在已经是37了,那么这时候干嘛。第二步。T1线程在自己的工作空间,在自己这个线程所属的工作内存里面,已经将值从25修改为37以后。他将要把这个37干什么呢?写回给主内存。这一步能跟上,那么这个时候我们第二步本地工作,内存T1自己改为37,以后将要把这个值啊干什么写回主内存37。
13:06
这个时候能跟上。但是注意。这话T1第一次拷走25,这是我从原件那拷贝过来的。第二步它改为了37,第三步我写回主物理内存。但是抱歉。T2T3这个时候并不知道主物理内存的值已经从原来的25修改为了37,我们必须要有一种机制。只要有一个线程。修改完自己的工作空间的值并写回给主内存以后,要及时通知其他现场。这样及时通知的这种。情况就俗称GMM内存模型里面的第一个重要特性,俗称可见性能理解。
14:03
也就是说,某一个线程你修改了值并写回主物理内存以后,另外的线程要马上能够知道,OK,我手上这个25已经是不是最新值了,作废,我们需要重新回去拿到最新的值,这一步能理解。那么这个时候请大家跟着老师来先熟悉什么叫可见性,也记一个线程,修改了主物理内存的值。主物理内存的只要只要被修改,其他线程马上获得通知。假设今天。晚上我们呢,需要加课,只要。杨哥给班主任一说,班主任是不是马上会在你们班的微信群里面艾特所有人,大家是不是马上立刻现在就能看到,知道今天晚上要加课。否则今天晚上可能你就请假走人了,那么也就说什么只要有变动,大家立马可见,立刻收到最新消息,这个就叫可见性,OK,那么也就是说什么是我们GMM内存模型里面的第一大特性,那么这个时候再来看。
15:14
由于Java虚拟机运行的程序实体是每一个线程就干活的,是不是一个具体的线程啊?每个线程被创建的时候,GM都会去分配一个工作内存。什么意思啊,就是这个线产他自己的那份。工作内存是每个线程的什么东东?只有数据,也就是说现在按照这张图来说,杨哥这儿用了三个线程,就三个线程,就好比什么每位同学都穿着裤子,每一位同学裤子上都有自己的口袋,每一位同学那个口袋就是自己的工作空间,这么说听不听得到?好,那么接下来请看。Java内存模型中规定所有的变量都存储在什么内存,主内存,也就是我们硬件上插上的那条内存条。它只有一发。
16:02
主内存什么鬼共享,那么否则你不可能说主内存只允许CPU用,不允许显卡用,不允许硬盘用,不可能对不对,所以说主内存的东西是共享。来,所有线程都可以访问,请看按线程对变量的操作就是。读写这种操作必须在什么中进行?工作内存,也就是说我现在原值是25,我拷贝回自己的工作内存里面哈,我在这块改,我不是直接改主物理内存,这一步听不听得到?过来。首先要将变量从主内存拷贝回自己的工作内存。现在有两个内存,一个是我们硬件的叫主物理内存,它共享一个变量,比方说A级等于25岁,然后这儿有两个线程或者多个线程拷回到自己T1线程,第二线程,自己的工作内存空间。一个是主力内存,一个是现成的工作内存。
17:03
然后对变量进行操作,比方说25变37,操作完成后再将变量干什么写回主内存。好,它不能直接操作主内存中的变量。各个线程中工作内存中存储的是主内存编程中的什么变量拷贝副本?那么也就是说。我从这。是不是写了个东西叫变量拷贝,也就是从主物理内存拷贝了三份25,分别在各自的现成的工作内存,这一步同学们到这儿能跟上。OK,那么继续,我们讲慢一点。因此,不同的线程无法访问什么对方的工作内存。你的钱包和我的钱包一般礼貌而言,我不能动你的钱包。我可以借用你的手机打个电话,但我不能说把你钱包打开,我抽他两张钱爽一下。好。线程间的通信传值必须通过主内存来完成。那么也就是说,请看。
18:05
这个主部内主内存就是大家硬硬件上插的8G的那个内存,现在有一个六出来的对象,对象是在堆里面,整个虚拟机是不是也在内存里面。那么我们的STUDENT25岁A减年龄25岁,这个是共享变量,然后按照Java干嘛?跟缓存的这种工作模型GMM,它会拷贝走。共享变量的初始值25 25ab2个线程各自拷贝一份,分别在线程A的自己的本地内存,也就是我们这说的县城的工作内存里面。也就是你们个人裤子上的口袋,每人是不是穿一条裤子,没有光屁股过来上课的吧?他们过来。你自己改完以后,注意需要将你的变量干嘛写回主内存。
19:01
那么也就是说,你这拷贝过来的共享变量的副本初始值是25,你噼里啪啦做了一通运算,37了,A线程已经将结果是37,这只是A知道。他要将这个结果写回。共享变量,那么也就是说把主内存的这个A级从25变成37,第二步同学们能跟上。之后。由于线程间的通信,我们两个是不知道的。就好比说什么一个西城区的售票员和一个什么东城区的售票员,咱们两个各卖各的,我卖完了,我只知道这个总数发生了变化,但我卖票之前不可能给人家打电话说,诶,我告诉你,我要卖掉第23张票,你见过售票员之间,他们两个之间卖票的时候需要先电话确认的吗?不可能,对不对,同学们,所以说这个时候干嘛?言下之意,第一步25读到各自线程的工作空间里面,这个只是25,第二步线程运算完了以后,改为37,线程A要把它写回主内存,把共享变量从25变成37,第三步就是我们的可见性。
20:07
要让其他县城马上就知道。主物理内存这个唯一的值A级已经从25变为37,我们必须要有最新消息,第一时间就要通知我,这种能够第一时间通知的机制就叫Java内存模型里面的可见性,听懂了吗?好,那么我们可见性的内容就给大家介绍到这儿。
我来说两句