00:00
各位同学大家好,我们继续通过上一个案例,我们用八种锁的演示情况给大家介绍了我们的SYNCH到底锁的是什么,那么什么是对象锁,什么是类锁,对于我们的静态同步方法,普通同步方法,甚至包括我们那个前面提了一嘴啊S。This,这个是不是叫同步代码块,那么一般snchize主要就是这三种方法的体现和作用,OK,好,那么接下来我们从更深入的角度,字节码编译的角度来看一下底层的S到底是如何实现,基于M是怎么会知道你的代码里面就有S这个关键字。然后持有所。进行资源的绑定好,那么接下来同学们我们先来看一下文档。GDK源码里面,比如说我们notify方法啊,就是那个SYNCH是不是有wait和notify这个里面它有一段说明。他说一个县城啊。想变成这个对象的莫塔,就相当于说一个线程啊,想持有一个锁的话,In one of three with,就是三种方法里面你至少要拿到一种第一个执行一个S的实例方法,那么好。
01:12
相当于就是我们这样的第一种情况,哎,我们前面强调过,这个时候呢,它呢拿到的是不是就这个,说白了对应着我们的是不是就是对向所好,这是第一种,第二种the body of a synchize state,那相当于你看the body是不是叫做同步代码块的意思啊,那相当于说就是我们这一段,那么当然谁进来先持有这一个对象,这一个对象是什么,具体都可以啊,谁持有这个对象了,谁持有这个所,这是我们的第二种情况,第三种你看。对于对象的什么Type Class,哎,执行一个snchize state static静态同步方法,那么也就是我们这儿的第三种,好,这个就是我们一般原则下面三种think,它所的它所有的用法和持有方式,那么接下来这三种都执行完了以后,我们可以最终获得我们八种所的结论,然后我们用自解码翻译给大家看一下底层又如何实现,那么八种所的案例实际体现在三个地方,第一个。
02:14
作用于实例方法,当前实例加锁进入同步代码。之前要获得当前实例的锁,哎,也就是我们常说的对象锁。第二种作用于代码块,对括号里面配置的对象加锁,那么括号里面的对象谁持有,谁持有这把锁,谁加锁,OK,第三种作用于静态方法,那么当前的类加锁进去同步代码之前要获得当前类对象的锁,所以说。对象锁、类锁,然后括号里面配置的对象假锁就这三种。好,那么接下来同学们我们从自建码的角度来看一下我们日常开发过程当中写的一个SYNCH,它底层是如何变现的。那么来这介绍两个小命令,就是Java p,然后呢杠C和杠V,来首先Java p是反编译,那么就是查看一下我们这个自建码里面它是怎么写的啊,那么在这块呃,有需要的同学呢,可以下去。
03:12
B站上搜索一下这个宋洪康老师所讲的GVM实战,好,我们这儿就不再多说了,一句话,杠C代表是compile反编译的意思,假如你需要更多的信息,可以Java p,杠V,那么这个V是verb,那么可以输出更多附加信息,也就是这个自建码里面的行号啊,本地变量表啊,反汇编的一些更详细的信息,那么这两个我们都。在实际工作中是常用的两个参数都给大家来做一下讲解和演示好,那么下面根据前面所讲几种三种实例方法,代码块和静态方法,我们挨个挨个来,下面请看SYNCH的同步代码块,我们先写一个案例啊,由于这个八所这个案例呢,我们就不在上面改动了啊,那么来。假如说现在。我呢,嗯,Object object等于new object来这个时候我在这个类里面。
04:06
New了一个实例对象,它呢可以作为一把锁。那么public word1。Object来。我们打印出来。哈,这个时候是不是我们的同步代码块。OK,那么相当于说我们在这儿。跑一下。给它的字解码生成等等等等啊编译生成了以后,当然我这个里面may的话呢,没有执行哈,没呃,May里面的话没有写任何东西,但是呢,它的字解码,它底层的class文件是已经生成的,那么我们下面用。编译的方法来试一下,那么对于我们的ARC,它肯定是在target class这一块挨个找下来,好,那么同学们我们的包名是goc lock,好,那们搁到这reload from磁盘保证是最新的,大家请看open term terminal一个什么命令终端,好那么命令终端了以后,那么同学们我们Java p-C,那么这就是lock。
05:08
Single DEMO,那么我们这个类就这这个名字,OK表示的是在当前目录下面,我们呢,反编一下这个class文件,看看它有些什么,那么此时我们来看一下。我们用的是第一种。同步代码块object,那么看看Java里面是这么写,那么底层源码里面写成什么样呢?我们做一下执行。来,同学们一目了然,很简单啊,更多的我们就跟我们不相关的,我们就不再陈述,我们只说要紧的啊,至于其他这些事是什么,那么大家可以下去呢,查阅其他相关资料好。首先。M1方法。不用多讲,这的第十是不是刚好是我们这第17,对对上了吧,所以说这个时候如果你用同步代码块,那么同学们。一这个方法它是这么干的。第一个进来了以后,大家请看它和这有个莫塔N,它代表什么索监视器获得了并进入,然后进来以后,你正常执行完毕了以后,它会有个。
06:12
那么这个是什么?说明要退出,也就是说这一行代码只要哪一个线程持有这把锁了,谁持有谁进来,进来以后干活,用完了以后再将其释放,进入释放,OK,所以说我们会明白,原来对于Java s同步代码块而言,底层是靠模拟。N和莫尼塔exit来保证所的获取和示范。好,那么接下来同学们,我们来看一个东东。一进一出好理解吧,配对,但是会突然发现。在最下面还有一个X诶。从头找到尾,我们现在只看M1啊,同学们,别的我们不看。我们只写了这么简简单单的就这么一行,那么肯定是这,那么在这了,以后同学们可以看得出。
07:03
规定着我们的动作15,也就对应着我们的赵德六一定是进来了,对吧?15函数进来了,十有锁,一个进来一个出去,这个倒好理解,为什么现在是一个进来居然会发现有两个出去exit呢?那么这是为什么呢?那么来请同学们注意。我们反编译了以后,和我们这儿一模一样,这个和这个一一匹配,好说为什么会多出来一个呢,那一对二了,不打匹配了呀,这是为什么,你们听好。这块它所涉及的意思是。S是同步代码块,是持有锁加锁的。操作,那么你正常执行完了,进入正常释放,好说,但是特别害怕里面又会出现一些异常的话,会有一些其他意想不到的情况,要保证你能够释放锁,所以说如果你正常释放是走他,如果你里面的程序啊出了一些错乱,也要保证能够释放这个锁,所以说是走第二个,大家请看第二个后面是不是有个A子肉抛出异常,所以说它这个是保证你正常情况可以退出的持有异常情况也可以退出,所的持有是这个意思,好,那么所以说呢,我们可以获得S同步代码块使用实现的使用模ENT和模exit这里直立来保证。
08:24
石油所释放所好。那么接下来有个小细节,一定是一个entry。派两个X吗?来,同学们。一般情况下,咱们就是一个N对应着两个xit,你去反边以后只要用这么写,大多数就是一对二,但是呢,也会有其他情况啊,那么同学们假设啊,你肉。你非要啊,当然这个,呃,我不推荐大家去用啊,我们只是说在教学上。我们来这么说一下,好,我们现在呢。又加了这么一行,也就是我故意会抛出来一个,那么相当于说你正常执行会抛异常,假设这个程序里面错了也会抛异常,那么此时的时候我们要面临着哪些情况呢?那么跟刚才一样加YP干。
09:12
C look新点class来,各位同学。和刚才一样。这块是不是打出来了,那么来同学们entry。然后呢,Xit这个没问题吧,但是此时同学们请看进来了以后,这有几个,这有一个异常,这有一个什么异常,哎,这两个。正常退出,异常退出,但是此时一个N出只有几个一个exit,哎,所以说在这块的时候,这种极端情况呢,那么请同学们呢,要了解一般情况下是一对二,但是如果你非要这样情况呢,也会有这样的话,一对一的这种情况啊,当然这个呢,就是一点偏门知识了,不要求大家掌握好,那么这个呢,过我们得到的结论,只需要记住这一个同步代码块,人家靠的是模。ENT和莫塔EXIT1对二,一进一出来保证,那么下面普通同步方法呢?好,那么同学们。
10:08
我们搁到这儿。把这块呢取消来public synch vo2这个方法。来吧。我们的执行呢,也就是我们的hello s。就这么一个就行了,好吧,那么M2来。等它执行完好,我们继续回到我们的字节码,注意,现在已经变成了。普通的S的同步方法来看一眼啊,我们的自建码,那么这个时候我们的Java p,由于我们这个呢,呃,给需要有看到更加扩展的信息参数由C换成我们的V。Look think,加class来,各位同学。接下来我们会看到,对于我们的M2来。大家一眼这一行出现了,那是不是代表我们的M2这这块代码块就看到了,那么在这段代码里面,我们会发现,只要你加了snchize,它上面会加一个ACC synchize这么一个标识。
11:10
哎,所以说Java虚拟机它来读这些字解码,相当于就发现有这么一个ACC访问的S标识,他就晓得了这个是一个同步方法,那么自然而然会给你加锁,实有锁,保证同一时间段只能有一个线程进来访问,好所以说我们在这儿对于普通同步方法,我们用干V,那么前面说过啊,我们需要这个,呃,附加信息,包括行号,本地变量表等等,所以说呢,我们换了个参数,C和V都给大家做一下演示,那么反编译以后,Synchize,这会有个ACC synchize的这么一个标识,好的,那么普通同步方法,那么得到的效果和结论就是。调用指令将会检查方法的。这么一个标识是否被设置过有?说明执行线程会将先持有模拟锁,先去强锁,然后再执行方法,最后在方法完成,我们刚才我们前面说过了,正常退出或者异常退出的话,都会释放我们模拟它,那么Java虚拟机底层就会晓得,如果有这么一个东东,OK,同步方法,我就知道后面该怎么办了。好,这是我们的第二种,那么第三个是什么呢?SYNCH是吧,静态同步方法来,那么各位同学和刚才有什么区别呢?
12:24
我们来这儿啊。我们不妨呢把静态和非静态的呢。都写到一块儿吧,那么这个呢,是我们的。静态同步方法,这是我们的方法,M3,好吧,那么但等它呢,运行编译完成,好,那么各位同学,那么这样的话呢,我们还是原来的目录,这有两个方法呢,M2M3,顺带也看看这两个有什么区别,我们来进行一下对比,那么来Java p,但V,此时我们先去看我们的。M3这块新的知识大家请看,对于M3我们加的static s代表是不是静态代码,OK吧,静态同步方法,那么此时public public静态,静态同步方法也叫这么一个,和前面的我们的M2的方法是一回事,那么对比两个,他们有什么细节上的区别呢?大家请看,这个是普通同步方法,只加了这么一个。
13:23
ACC synchized没有加static,但是对于他static synchized加的是ACC static和ACC synchized,那么如果有这样一个,他就会明白了,哪一个是类锁,哪一个是对象锁,我们这个M3就是我们的类锁,我们的M2这个方法加的就是普通synchized,那么就是一个什么对象组,OK,好,所以说我们这儿也可以获得。他们使用静态和这个访问标识区分该方法是否是静态同步方法,由此决定它是不是内锁好。那么各位同学,这个就是我们从更深度的自检码的角度给大家介绍了S3种持有所得方式,同步代码块,普通同步方法和静态同步方。
我来说两句