00:00
来咱们对呢,虚拟基站有了整体的认识之后呢,下边咱们来看一下站内部的结构啊,我们就层层向里啊,就像咱们一开始说的,大家之前看到的是一个大象,然后我们接下来呢,是看到大象的几个不同的身体的部分啊,有腿,有鼻子,也有头,有耳朵是吧?然后呢,我们再深入到它的这个,比如说这个鼻子上,然后再看它具体的细节啊,就涉及到一个一个的细胞了,那下边呢,我们就再深入到虚拟机站里边,看看站的存储单位是什么啊好,我们来看一下。站呢,就是我们平时经常说的这个概念了哈,那站里边到底是存着什么呢?诶,这里边我们首先明确一下,每一个县城都有自己的站啊,这个咱们都已经说过了啊,它是线程私有的,那站里边的数据呢,都是以战帧为格式存储的,或者呢,我们应该说叫以战帧基本单位进行存储的,哎,就好比是咱们看到大象的耳朵呢,是一个一个的细胞,哎,这儿呢,就相当于是细胞,不管是耳朵也好,还是呃,其他的这个位置的身体部位也好啊,我们说它的一个基本单位就是战争。
01:08
啊,那多个细胞构成了大象的一个器官,那我们说这个战针呢,诶就存在于我们这个站里边,不停的进行一个入站出站的操作,啊,那就战呢,就整个就运行起来了,说在这个线程上,那正在执行的每个方法呢,都对应着一个战争。在这里边儿呢,就提到了方法和我们这个战争的一个关系,哎,我们说什么关系呢?就是方法,注意啊,这个大家要记住它方法跟咱们的战争是一一对应的关系,就是一个方法的执行就对应着一个战争的入战。一个方法的执行结束,那么这个战争呢,就会出战,所以他们是完全一对一的关系。那这个方法呢,大家并不陌生,就是咱们Java里边呢,诶定义的这个方法啊,咱们说在面向对象的这个世界当中,咱们Java语言是个面向对象的语言哈,在面向对象的这个世界当中呢,类和对象,哎,咱们是这个最基本的概念了。
02:11
啊,类和对象是基本的概念,那么对象里边,或者说我们在定义类的时候呢,最基本的两个结构呢,一个叫做field啊,咱们翻译成平时叫属性了哈,呃,这个咱们说这个,这个相当是一个回顾了哈,诶面向对象里边,我们说最近的概念呢,一个叫做类,这咱写这个,这相当于是一个复习了哈。嗯,这个面向对象里边,我们就写叫op啊,它的基本单位。呃,基本单位或者叫叫基本概念,呃,叫类和对象啊,这是一个问题,第二个问题呢,我们说这个类中,或者说咱们类创建的对象当中,这个基本的结构啊,两个啊,一个呢,我们称叫称作呢,叫做field,呃属性啊,另外一个叫方法,这个翻译成属性也好,这个咱们中文呢。
03:00
可以叫属性啊,也可以呢叫做字段,呃,像我们数据库里边呢,我们习惯上叫字段啊,其实呢,哎,在官方的这个翻译过来的书里边呢,诶把它呢,经常也称作叫做玉啊,是这样的概念,哎field跟method,这是我们说是一个类中的最主要的构成的元素。那最主要构成元素,当我们实例化一个对象以后呢,这个字段呢,就可以理解成是你这个对象的各个器官,那方法呢,就可以理解成一个对象的各种呃,一系列的行为啊,那方法呢,其实就是程序用于执行命令的一个关键啊,那我们现在呢,去调用一个方法,方法呢说对应的这个战争,那我们现在呢,就回归到这个战争层面啊,来了解了解它了啊说战争呢,是一个内存的区域,是一个数据集啊,战争里边又分成很多部分,咱们一会儿说啊,它维系着方法执行过程当中的各种数据信息啊过了。好,那既然呢,我们说这个,呃,站里边的基本单位呢是战帧,那么站的操作呢,就只有入站和出站啊,它就是我们数据结构中的一个战的结构哈,呃,它遵循的是叫先进后出,或者叫后进先出的原则啊,这是站的这个通用的特性,那只有压站或我们叫入站啊,Push,然后出战呢,胖MP是吧,只有这两个最基本的操作啊,这个大家要清楚啊,所以呢,在一条活动的线程当中。
04:21
啊,一个时间点上只会有一个活动的战争。哎,在一个时间点上只会有一个活动战争,那么我们只有当前正在执行的方法呢,这个战争呢是有效的,我们就称为叫当前战争。那与当前战争对应的方法呢,我们称为叫当前方法,那么定义这个方法的类就是当前类啊,就是这有三个名词啊,咱们明确一下,其实呢,也比较简单啊,比较简单,这呢,我也画了一个图啊,画了一个图,这个图呢也比较清楚,比如说呢,我们在这个main方法当中啊,咱们调了一下这个方法一。诶,这个main方法呢,那就相当于咱们的一个主线程啊,那这呢,就是我主线程对应的我们这个站啊,那在这个站里边,我直接就调用方法一,那方法一呢又调方法二,二又调三,三又调四,那么当前呢,我们正在执行方法四,那这个方法四呢,对应的这个战帧就处在站顶的位置。
05:17
啊,这个站点的这个位置,那么它就称为叫当前战争。诶,它就是当前战争,那么当前战争对应的这个方法呢,就是当前方法,哎就是这个意思啊,它有个一一对应的关系,哎,这个清楚,嗯,只有当前这个战争我们正在操作的,它才是有效的啊,这个应该很很很容易理解啊,说直行引擎呢,运行的所有磁解码指令只针对当前战争时这个进行的,这也很好理解啊,当前我们操作的是哪个方法,那它才是有效的,那我们就在执行它是吧,那你下边这些这个其他的这些指令呢,那目前是执行不到它的,因为你在执行,比如说我们这个方法三的过程当中,你执行到了方法四了啊,所以这个这个自己码指令呢,就跳转到这个方法四这块来执行了,哎,那三的这个自己码指令呢,就先停一停,那我们寄存器当中存储的也是当前战争的这个自己码指令的那个操作地址。
06:13
啊,他的那个偏移的地址,那当操作完以后呢,他再再操作咱们这个方法三啊。呃,如果在该方法中调用了其他方法,那新的战争呢,就会创建出来,放在战争顶端,成为新的当前战争啊,这个很好理解啊。嗯,那基于咱们刚才说的这个过程呢,咱们还可以写一个代码,呃,咱们还在这个第五章当中,呃,不妨呢,我们就再新建一个package。好,在这里边我们写一个具体的一个程序啊,也比较简单,Sta frame它的一个测试。好,首先呢,我这写了个main方法,嗯,May方法当中,我们先这样啊,先定一个普通的方法一。行,哎,这儿呢,我写一句话。哎,一开始执行。
07:03
OK,然后在这个METHOD1里边呢,我们调研一下这个方法二啊,方法二咱们还没定义。OK,然后呢,我们定一下这个方法二。呃,权限的话呢,这个不重要啊,这个我就写成private也可以,呃,方法二呢,我们一上来也是有这样的一个操作啊,我把它呢也CTRL一下。这个呢,我再调一个方法三,方法三呢,没有我们创建一下。这个不妨我们让它有个返回值之后,就写成个int型的返回值了,行,然后在这里边呢,我们CTRL。喂一下。呃,方法一方法二,这个方法二呢,咱们也让他返回一个值吧,比如说这个是个int型的值。诶,这个是int型的,然后我们在这个位置,咱可以去定义一个,比如说I这是一个十。
08:03
然后最后呢,我们return一下这个。先return一下这个I,那这呢就不能叫执行结束了啊,我们说叫即将结束。诶可以这样啊,因为我们return执行完以后呢,这个方法才会结束,然后在二里边呢,又调用了这个三三呢,不妨我们换一个返回值啊,一会儿呢,咱们说一下这个方法结束哈,诶要稍微看一下这个,诶反编译得到的这个自己码指令,所以我这呢就用了两个不同的返回值类型,嗯,在这里边呢,我们定义这就这就不用了哈,咱再定一个double型的吧。我叫一个街,这呢是叫10:20点零。哎,这我就随意定义了一个值,然后呢,我们在这个里边呢,把这个接呢做一个返回,诶这呢是呃,这个是方法二了啊。方法三。诶,这个呢,也是叫即将结束。行,然后返回的这个接呢,我们就呃到这儿来接收,诶不妨呢,我这就用一个,其实还是接也没事啊,换一个字母吧,叫M来接收,这呢我们做一个强转,呃,Return呢,我们返回一下I加上M。
09:12
哎,做一个返回啊,返回的这个值呢,我们在这个方法一里边来调用,这呢我就没有再用这个值了,哎,这个不重要啊,行,那大体上呢,就是我们说这样的一个过程,在may的这个方法对应的这个线程当中,咱们呢,去调用一下咱们这个METHOD1,其实呢,我也可以把这几个方法呢,都定义成个静态的也行啊,这都没问题,咱们调一下这个METHOD1,一里边又调二,二里边又掉三啊三呢结束啊,整个就是这样一个过程,好,那我们先跑一下这个程序。这个大家应该都能看得懂,非常简单的一个代码。诶可以了啊,然后这呢,我们就会看到,当咱们在这个主线程当中,当然呢,这个魅方法其实是应该,如果咱们要具体化的,它应该是先有这个战争对吧,但是只不过呢,因为这是我们当前线程嘛,主线程里边,那你第一个方法肯定是没方法嘛,只不过我这块呢,咱们先忽略掉这个没方法啊,不考虑它了,就然后呢,我们看一下这个METHOD1,它呢是先来执行,所以这个呢是方法一,然后方法一在执行过程当中呢,当中呢,我们就调用了这个方法二,所以呢,每一个方法都对应着一个战争,所以呢,我们这个方法二呢就进来了,那此时呢,其实这个二在这个时候呢,它是当前战争啊,那在调用二的过程当中,咱们又调用三了,所以在二的上面又放了个三。
10:31
诶,那三呢,就是当前战争了,二就不是了,然后三呢就执行结束,三执行结束呢,他就出战了,他一出战呢,诶二又变成当前战争了,然后再三出去,二变成当前战争的时候呢,仍然是由咱们说上一节讲到的,呃,叫程序计数器啊来指定咱们这个执行引擎要指定的,呃,执执行的这个下一个指令啊,就跳转到这个METHOD2这块了,哎,他呢,二又变成了当前战争,哎,然后二执行完以后呢,二也出战。
11:03
诶,然后呢,方法一对应的这个战争又成为了当前战争啊,那我们要加上这个没方法的话呢,那就是没方,这个方法一执行完以后呢,你在下边再补一个这个魅方法,哎,它呢又变成当前战争,诶就可以了。诶,就是这样的一个过程啊,所以大家你要看我们这个执行的时候,你会发现它是有这样的一个套路一样是吧,一层层这样包含的关系。那除了咱们这个METHODS3之外,它是最上边这个了啊,那其实我们像METHOD1METHOD2,他们其实是有两次机会成为当前战争的,就他最开始执行的时候,这是他的机会,然后他再用别的方法时候呢,他就不再是当前战争了,然后当其他方法都执行结束以后呢,诶又回过来执行他,他又成为了当前战争。包括咱们那方法也是一样,那一上来呢,他就是当前战争,然后最后结束的时候呢,也是他,哎我们讲叫啊有始有终是吧,诶最开始是他最接受,他不会出现这种交叉的情况啊,所以咱们出现的其实都是这种像嵌套的这种情况一样。
12:06
那不会出现说,诶这是一个这样套着,这这是错误的,咱们说方法也不能这样套着用是吧,你也是在一个大括号里边,呃,再去包着另外一个大括号,都是这种嵌套的格式啊。行,那只有你最里边的,或者叫最顶层的这个战争,它呢,作为当前战争呢,它就只出现一次。哎,这个呢,比较好理解啊,行,这是这个事儿,嗯,我们要是再再再再来体会一下的话呢,其实也可以这样啊,就是大家呢,在我们这个MASTER1这块呢,加上一个断点,然后我们可以做一个debug。诶debug debug呢,这时候我们就可以看到这个may这个方法,诶首先呢,在我们主线程当中,May方法它现在正在执行,诶马上呢又进入我们METHOD1了,咱们进入METHOD1,诶你会看到在may上面呢,加了一个METHOD1,哎METHOD1呢继续向下执行啊,METHOD2呢,我们也呃进入进去啊,这就进入METHODST2了,那二呢又在一的上面了,所以二呢现在是当前战争,呃,这个对应的这个战争是当前战争啊。
13:09
然后接着呢,往下执行。诶执行到这个METHODS3,诶再进入,好,你看这个METHOD3呢就进来了,诶这就是就像我们一个战争的这个结构一样啊一四在它上面呢,进行一个累加三就是我们当前的这个战针,然后呢,诶三继续往下走,诶执行,诶这就出来它这个结果了哈,然后呢,Return,诶一直行好这时候呢,我们这个METHOD3呢,就执行结束了,那它呢就出战了,那METHOD2呢,诶对应的战争又是当前战争。然后依次呢,再向下。诶,然后再走,那METHODST2呢也结束了啊出战,那我们METHODS1呢,又是当天战争,然后再依次向下。好,METHODS1呢也执行结束了,那这时候呢,我们这个may方法它呢又是当前的战争,然后再向下执行,诶may方法也执行结束了,那当前战就结束了,那当前战结束主要是因为我们这个主方法内方法结束以后呢,它对应的这个主线程就也结束了,那主线程结束了,所以我们主线程跟他这个生命周期一样的,这个战争呢,诶自然而然的也就结束了。
14:20
哎,应该描述的比较清楚哈,诶大家应该能够诶看清楚这样的一个过程。好诶,就是我们这个图里边画的这个事情,呃,1234这几个方法依次这样去执行进来,诶这个图呢,我在这儿也提供了。啊,其实这个事儿呢,比较简单哈,不用过多的跟大家去啰嗦了,哎,这个方法四呢是当前正在执行方法,所以这个战争就当前战争,那你这个战争如果执行完了,那这个三呢就变成当前战争了。哎,就就这么个事儿呗,是吧,三又执行完了,二就是当前战争了。诶就是这个道理,嗯,很很容易是吧,哎,我这就给他复原了,就啊行这呢,就是咱们说的这个,诶依次执行的这样一个过程,那这样一个事情啊,行这个呢,咱们就过了,然后呢,咱们再看这个。
15:07
说呢,不同的线程当中所包含的战争,注意不同的线程啊,所包含的战争是不允许存在互相引用的啊,因为不同的线程有不同的这个站嘛,这个不同的站之间他们是数据不能共享的,咱们说这个不同的线程他们可以用它共享的在进程,同一个进程当中的堆空间,包括这方法区都可以,呃,他们这个站呢,是各自私有的,所以就不允许互相引用了啊,这一定要小心一点啊,即不可能在一个战争当中引用另外一个线程的战争。啊,这这这就很好理解了啊,这个画一个简单的一个小图啊。嗯,把这个我先全选一下干掉啊。行,就是你这是一个战帧,这是一个战争,嗯,这是一个战,这是一个战,这是一个战,三个站呢,就对应的三个线程是吧?哎,这里边的数据,这里边的数据,这里边数据他们是不可以在这一个站站当中去你调用这个的数据的啊,因为这个线程之间他们针对于站来讲啊,是隔离的,哎,这要注意一下这个问题啊,嗯,这个还记不记得,咱们讲这个,嗯扎va虚拟机就第一章当中提到说阿里是吧,诶阿里这个虚拟机呢,它以一个新的一个技术,这个技术呢可以实现。
16:31
这个不同的虚拟机,诶我们说虚拟机呢,都有一个一个的这个实例啊,虚拟机这个实例一,呃,其实就对应的一个进程或者我们一个程序了啊,然后它跟第二个实例二,这相当于两个进程,它呢可以实现在进程之间是可以共享数据的啊,其实呢,使用的是对外空间了啊,其实这个也是一个很好的一个技术,这个之前咱们讲过啊,好像是呃JCH吧是吧,我记得是这个技术啊,诶这个大家回去可以看一眼也行。好这个就过了,那这个我们就删掉啊回过来。
17:04
那下边一个说,如果当前方法调用了其他方法,那么在方法返回之际呢,当前战争就会传回此方法的执行结果,给当给前一个战啊前一个战争,接着呢,虚拟机就会丢弃当前战争,使前一个战争呢重新成为当前战争。哎,这个也很好理解啊,然后呢,说Java方法呢,有两种返回的返回这个函数或叫方法的方式,一种呢是正常的函数返回。嗯,使用的是return指令,这就相当于这个方法呢,是正常执行完了啊,叫return指令,然后另外一种呢,是抛出异常,呃,两种方式不管哪一种呢,都会找,导致我们这个战争呢被弹出,诶这里边呢,抛出异常指的是我们没有处理这个异常啊,比如咱们要在一个方法当中,比如我们这个,呃,METHOD3当中,我们要有一个异常呢,咱们自己给try catch了,这个其实还算是正常的返回。诶,我们这个抛出异常指的是你没有处理这个异常啊,那你要没有处理的话呢,比如说咱们METHOD3中出现了未处理的异常,这个整个线程会结束吗。
18:09
大家想。其实不会是吧,诶或者说呢,不确定的啊,就是你这个METHOD3呢,你要是出现了未处理的异常,它呢直接就把这异常抛给了METHOD2了,然后METHOD2呢,看看有没有进行过拆开处理,如果也没处理呢,那接着往上抛,抛给METHOD1,那METHOD1呢也同样的看看有没有开,如果没有再抛给may may呢,这里边可以处理,如果may也没处理,那这个may呢,就相当于是还是以这种方式来结束的,那整个虚拟机我们就给它挂掉了。啊,那如果说啊,这个大家跟上这个思路哈,这样跟上这个思路呢,其实理解这个问题它它不困难啊,如果说咱们在这个METHOD1当中。注意啊,我在这个MESSAGE1当中出现异常了,这个咱们举个简单的例子也行,比如我这儿呢,我写一个呃,说这个may啊,它呢,呃正常结束写了一个这语句啊,然后呢,在这个METHOD1当中呢,我就输出一个操作,我就十出以零,这个大家都知道呢,这是一个异常了,那么METHOD1中运行中出现这个异常了,它会把这个异常呢,那正常的就抛给咱们这个may方法了,那may方法显然现在也不知道,没有进行TRY开的处理,哎,那我们会发现呢,这一条语句呢,就不能够正常执行了,跑一下。
19:33
哎,大家看就出现了异常了,然后这个诶METHOD1呢正常结束了,但是我们这个may方法这个语句没结束,那也就是说说什么呢,就是我们对于METHODS32他们都算是正常接束的,METHODS1呢不是正常接束的,它抛了一个异常,它METHODS1呢属于是这种方式啊,那抛给may方法以后呢,酶方法呢,也没有处理,相当于这个异常呢,在这儿就发生了,它呢may方法也是。
20:01
这种方式结束的。那那如果没方法想用第一种方式结束呢?你得写一个try catch。对吧,哎,我们把这个包起来,诶,我们这样给他做一个try catch的这样一个处理。诶这样处理完以后,当然这句话呢,你就不能写在这儿了,写这儿的话呢,它照样还是不会执行,对吧?诶我们得先放到这个finally当中,诶放到这儿当你正常执行结束以后,当然放到这儿的话呢,大家也可能也会有歧义啊,说你这个呃处没处理他都执行,因为finally嘛,对吧?诶我这样写哈,呃,如果你把这异常都处理掉了。那就再执行这句话,此时的这种may方法呢,它相当于是就是第一种方式正常执行结束的。诶,这个大家注意一下这个过程啊,我们再跑一下这个程序。那你看这个呢,是咱们主动让他报出来的哈,这个你就不要担心,哎,咱们让他报的,然后你看正常有个没方法结束,哎may呢,此时是以第一种正常方式结束的,哎这个只有咱们这个METHOD1,它算式方式二啊来结束的啊,咱们可以在这呢稍微写一写哎这个方法的结束方式。
21:10
呃,分为两种。呃,第一种呢,就是呃正常结束啊,以return啊为代表,哎,这叫正常结束,这呢我们是一个一啊,然后第二种呢,诶我们称为呢,就是诶这个方法出现执行中。诶出现未诶补货的异常。诶,未捕获处理的异常,哎,然后以抛出异常的方式结束。诶这就我们说的这个情况好了,这个呢,就是这个样子的啊嗯,那然后呢,咱们演示一下,那演示一下咱们刚才说的这个问题哈,我现在呢,诶把这个呢,比如说预计我先暂时的注释一下啊,我们看下这种呃,有返回值的和没有返回值的他们这种区别。
22:06
这个程序呢,我刚才注释了,需要我重新的再去re compel重新编译一下,或者大家重新跑一下这个程序也可以哈。那重新编译了,重新编译完以后呢,我们再回到这个控制台这块,咱们呢,把这个程序呢,进行一个反编译,这时候呢,我们是在这个第五章下边,所以CD点点。哎哟,写错了啊。好,然后CD。嗯,好,然后在这个下面,诶这个不是Java了。JAR1是吧,然后在这下边呢,我们现在把这个程序呢,进行一个反编译哈,呃,Jarp。啊,这个呢,不要加这个最后的这个分号啊。
23:00
好出来了,那出来以后呢,我们看一下咱们的METHOD1。哎,这个MS的一。METHOD1METHOD2METHOD3。啊,这个method。啊,这是may啊,它这个方法,这是构造器。但是方法不全啊。看着。这是MESSAGE1,我重新的再这个应该它自动都保存过了啊,我再重新的给他做一个编译啊,这是私有的,我把这个改成一个public了啊。在公共权限CTRLCCTRLV啊保存好,然后重新呢,我们再去做一个编译。那编译完以后,我们下边呢,再重新呢,给它做一个张P的操作。
24:03
那其实我直接呢,再点一下这个上方向键上就行啊,不用重新再写了,好出来了,出来以后呢,我们回过来看一下咱们这个METHOD3,最终呢,是返回了一个接,这个接呢是一个double类型的,所以你会看到这个METHOD3里边执行的这个code啊,一行行在最后呢,它有一个叫d return啊,这个D呢就是double的意思,哎,是以return的方式来结束的,然后我们这个METHOD2呢,我这个可以写成是一个int型的,所以我们会看到它呢叫I return,是咱们这个方法二,哎,这个呢叫I return。就是int类型。然后我们那个METHOD1呢,咱们是没有返回值的,所以呢,它呃,当然没有返回值,其实它后边也有一个return哈。所以大家你会看到我们这个M1呢,最后是就叫就叫做return,只不过呢,没有指明说你具体反馈是什么类型的了,哎,所以就是个return,所以呢,大家在写程序的时候,大家学Java的时候啊,诶我们像这种没有返回值的方法呢,最后你要就写个return是不是也是可以的呀。
25:03
诶,这个是没问题的啊,诶我们在这说明它是不会报错的,你写个return,呃不写return,最后呢,我们这个得到的这个指令里边,最后都会有return这样的一个指令,哎是这个原因啊,就是我们只能说呀,叫可以省略是吧,它其实是存在的,呃,因为方法的结束呢,呃,你要是正常结束的,它就是以return来结束的,哎,是这个意思啊行,那刚才呢,咱们说了这么多,关于这个站的基本结构,运行原理呢,咱们就介绍清楚了。
我来说两句