00:00
好,那么前面呢,咱们讲了使用S的一个呢叫同步代码块,一个呢叫同步方法来处理线程安全问题,这呢是在我们一开始有这个JDK的时候呢,就做了这样的一个设置了,那现在的话呢,我们说在JDK5.0的时候呢,又加了一种方式,你可以看成是5.0的一个新特性,说提供了更强大的线程同步机制,通过显示的去定义同步锁,把这个呢叫做同步锁了,或者你就叫做lock也行啊,让他呢来实现一个同步的效果,同样呢来解决线程的安全问题。哎,同样的来解决线上安全问题,那么这个lock的话呢,它实际上是一个接口。啊,是个接口,那我们要用的话呢,肯定不能说就用接口了,那我们得用接口具体的实现类啊具体的实现类的话呢,提到一个典型的实现类叫做lock。啊,使用这个类的对象,我们来解决线程的安全问题啊,这个不多说这个概念了,咱们直接呢,还是来举一个例子来说明,在这个扎一下,咱们去新建一个啊class,不妨呢,我就叫做这个lock的一个test。
01:11
啊,这呢属于我们叫嗯,解决线程安全问题的这个方式,方式我叫方式三吧。哎,前面两个呢,一个叫同步代码块,一个叫同步方法啊,或者说前两个呢,你叫合起来叫方式一,那就叫C的方式,这呢叫方式二叫lock的方式啊,哎,Lock锁这个呢是咱们诶JDK。5.0新增。诶的一种方式,好,那首先的话呢,咱们得先写个代码,让它呢出现这个线程的安全问题,那你就得先创建多线程呗,这里边的话呢,一个继承一个实现。嗯,写哪个都行啊,这样呢,我就先写一个了,写一个的话呢,我就先写一个,还用window。
02:05
Window这我写一个什么方式啊,继承和实现啊,其实都无所谓啊,就看大家想看哪个了,继承就CE啊,实现的就implements是吧,都行,那我就演示一个叫实现了,这呢咱们还演示一下这个卖票在这out enter一下。嗯,这个位置咱们在上面的先看。嗯,100张票,诶在这里边先挖一下。哎,这呢,我们就直接呢去买票了。嗯,这个咱们就写一个叫thread.current thread.name。
03:02
诶收票,然后票号为。哎,在这个呢,我们再来一个else啊。成,然后呢,在这个位置咱们进行一个测试,还有一个没方法造一个window对象。行,然后呢,咱们去这个thread。嗯,这个我写个W。Enter,哎,这个叫T。然后呢,造三个窗口。那接着我们去设置一下这个名字啊,这个咱们都写过这个代码了。
04:02
接着呢,让这三个线程的start。行这个代码呢,咱们就写完了,写完了为了让这个重票或错票出现的概率大一点,咱们这个位置呢,让他写了个sleep。好,我这呢还写了这个100毫秒啊out enter一下,处理一下当前的异常,这就写完了,写完以后呢,我们一执行,此时呢是存在线程安全问题的。那有这个重票啊,也有这个错票,好了,那下边呢,我们去解决这个线程安全问题,前面呢已经讲了两种方式了,下面我们说一个新的方式,叫做lock lock呢本身是一个接口,我们具体使用的呢,是它的一个此类叫做return lock啊怎么去实现,咱们直接来写这个步骤,在我们这个reable这个具体的实现类当中,我们声明一个属性叫做private,造一个returnlo这个对象。
05:01
Lock。这样。那这呢,我们就放到这了,那上午的话有同学问这样一个事啊,就是我们这个用eclipse的时候呢,我们去拗个对象,这里边呢,如果有好几个参数,你可以去选择哪个构造器,说在这的时候呢,有时候不知道该怎么选了,其实你在写的过程当中呢,它也会有个提示,如果呢,你那时候错过了,你把光标呢,放在我们这个两个小括号中间,这时候呢,我设置过这一个快捷键啊,Ctrl alt斜杠。这时候你一点你就能看到这个呃类每一个构造器,这呢,因为人家就只有两个构造器,所以就显示这两了,这个lo呢,你发现它有构造器,一个呢是无参的,一个是有参的,这个有参这个呢叫fair。范呢,你可以看到叫是不是公平。嗯,这个我要用这个无参的话呢,像这个fire设置的值是个false,呃,你也可以给它设置成是个处,这有什么区别呢?哎,你要是写成和true的话呢,我们现在创建的就是一个所谓的叫公平的一个lock。
06:02
这个时候呢,就会导致就是如果你这个线程的话呢,他他们进来的时候呢,有一个先后顺序,人家是先来的,这个是后来的,这个是第三个来的,那回头这个同步资源的话呢,我就会让他让人家一先执行啊,二后来的,那我就接着让二执行,让三再来的,那就让三执行,不会出现咱们执行的这个效果,说这个窗口一买买了票了,买了票一出去以后呢,诶下一刻诶窗口一又抢到了,你白让人家二跟三在这儿等着了。这就叫是不是fair公平,公平呢,就意味着呢,它是一个呃先进先出的,哎这样一个特点啊,哎如果呢,我们要是不写,相当于就是个false。这就相当于是false,就相当于咱们前面演示的那些情况,可能窗口一连着打印了好多张啊,这种情况啊,这呢我们就重心不在这儿啊,那主要呢,就是我们看怎么就同步了,先造一个对象,这是第一步。实例化,实例化我们这个re return lock,或者你说叫实例化这个lock也可以,然后接下来,接下来的话呢,我们说需要被同步的代码呢,是它。
07:10
哎,那我们就针对它呢来进行操作,怎么操作呢,我把这段代码呢,我放到这个踹当中。诶CTRLX,诶我放到CTRLV放到这,放到TRY当中,但是我这里边呢,又没有什么异常了,那怎么办呢?我就不用写catch了,咱们在这呢,写一个finally啊这样那么里边都需要做什么事呢?在这个TRY里边呢,我们一上来,诶先来执行这样的一个操作,就是拿我们这个lock呢,哎,有个方法就叫做lock。看这这呢,相当于就是调用方法。哎,这个呢,就有点像咱们呢,说那个线程叫获取了同步监视器啊,就从这个代码里边呢,就相当于被锁住了,保证在这个过程当中,它是一个单线程的。
08:02
当这个代码执行完的时候,或者你可能出现一些异常,那异常呢,这个我们也一定会执行这个finally的代码,在这个finally这个当中呢,咱们得给人家解锁一下,所以呢,哎,用这个lo点调一个叫unlock。哎,这呢,就是调用解锁的方法。那解锁方案叫unlock。哎,这样啊,这个呢,你可以说叫调用一个叫锁定的一个方法,哎这么着。好,这呢,我就写完了。哎,此时呢,我们能够保证的就是在我们这个串这个方法后边的这些代码呢,哎,它都类似于一个同步代码块里边的那个代码一样啊,是一个单线程的,那我们这时候呢,执行一下。哎,这时候你看都是窗口一了啊。
09:01
这么巧吗?都是窗口仪是吧?嗯,这个呢,看有没有写的有问题,嗯,把Y写外面了啊,没事啊。这个没问题。那这不是有交互了。行,这就OK了,那这呢,就是我们也改成了一个线程安全的方式了,那么大家呢,也可以去选择我们用这个lock的方式啊,来解决线程安全问题啊,那我们接下来呢,做一个事情,这也是一道常见的面试题。哎,什么题呢,就是咱们这呢讲了两种方式,第一个呢,大方向上是两种啊S。哎,那么C空的这种方式和我们现在讲的这个lock的方式,它的一个嗯叫异同。这个面积看看怎么打。哎,既然的话呢,他们两个都可以处理现场安全问题,有什么不同啊是吧,那这个呢,更多我们关注的是不同,你要非要说相同的话呢,那也很好答,那就是他们二者呢,是不是都可以解决现场的安全问题啊,嗯。
10:11
诶,或者说呢,他们两个就是用来解决现场安全问题的啊,那么这是他们的相同点。嗯,那么主要呢,咱们来关注一下二者的这个不同,那大家来看一下这个不同怎么去说明啊。嗯,你会发现呢,咱们这个lock的这种方式呢,它像是一种手动的锁定和手动的解锁。啊,也就是说呢,如果我们要是不执行这个lock方法的话呢,这代码是不是后边的都就成了这个单线程的一个情况了啊,而咱们呢,呃,讲的这个哪怕是这个词索咱们也可以说明啊,哎,在咱们讲的这个同步的方式当中,我把这个方法呢,声明成一个同步的了,那么它在调用完这一对大括号的时候呢,是不是自动的就会释放这个锁了,哎,就会释放这个锁,在这个过程当中呢,都是不可能释放的,只有执行完我们这个同步方法啊才可以,那要是以这个同步代码块呢来说也是一样的。
11:18
同步代款代码块呢,就得等你把这个大括号一直到到这个位置你都执行完的时候呢,它才会自动的把这个哎叫同步监视器给释放掉啊,咱们这个lock的话呢,它不是这种方式的lock的话呢,就必须呢,我们手动的去调下unlock,当然也比较灵活,就是你想在哪调你就在哪调,只要调了这个方法呢,它相当于就算结束这个这个同步的效果了啊,这就是他们二者的一个主要的区别,其实是啊,在这我们写一下就是我们的这个S的。哎,这个S的话呢,这个它可能是同步方法或者叫同步代码块啊,哎S这个机制呢,就是属于呢叫自动的,哎释放啊,就是在执行完哎相应的哎这个代码逻辑以后,或者叫同步代码以后啊,哎叫自动的。
12:21
呃,释放,哎,叫同步监视器。那这是它,那对于咱们lock来讲,它呢,哎,我们呢,相当于是一种手动的方式啊,Lock呢,我们需要手动的。你这个就更多的像是一个自动的了,哎,Lock呢,需要手动的呢,去这个呃,启动同步啊,这就相当于我们调的是这个lock方法。嗯,手动的去启动同步,然后同时呢。哎,结束同步啊,也需要哎手动的实现,哎手动的这个去实现啊,那这呢,咱们就必须呢去调一下这个叫unlock。
13:10
哎,这个方法呢才可以。行,这呢就是我们说的二者的一个不同啊,大家关注一下,那么在开发当中呢,咱们呃用哪一个呢?嗯,这个schize的话呢,其实一开始就有,包括呢,咱们看这个源码的时候,你会发现,呃,基本上呢,都会选择用SCH的,嗯,就是不管是这个我们这个在讲这个常用类的时候呢,你会看到很多啊,到时候会带着大家去看很多呢,这个这个这个代码都是线程安全的,它底层呢都是用的SQNE用loft呢还比较少,毕竟呢,它是JD5JDK5.0新增的一个新特性,呃,但是通常呢,一般咱们后来新增的这些呢,通常是不是都建议大家去用了,你的一个逆向逻辑来想,他如果说还不建议你用他后还新增呢,那不就白洗了吗?哎,他之所以后来新增呢,说白了就是建议你去用啊,为什么呢,因为这个lock呢,我们手动这种方式呢,就更灵活一些。
14:09
啊更灵活一些,这个我们在PPT里边呢,我这应该是也有写啊,就是大家呢,去使用这个线程呃,同步机制来处理安全问题的时候呢,建议呃可以优先考虑用lock。啊,这是细微的对比哈,其实你用哪个都行啊,建议呢优先呢用lock,其次的话呢,就用同步代码块啊,因为你进入这个方法体以后呢,我们再去分配相应的资源,然后最后呢,再建议大家用同步方法。哎,因为这个方法呢,整体是同步了,它里边呢就都是一个单线程了哈,哎,那呢,没有这个同步代码块呢,灵活一些,哎这呢,我们说大家在开发中使用的时候的一个建议的顺序,实际上呢,你用谁当然都可以啊。成这呢是咱们关于这个呃,Lock锁的一种说明,这个这是一道名人题,那另外一道名人题呢,那就是问说如何解决线程的安全问题,有几种方式。
15:18
那这个问题呢,大家就都应该回答了。啊,你说三种,那就是把同步那个C呢,说成两个啊,说两种呢,把它俩现在又合成一个了,同步代码化同步方法看成一个了都行,总之呢,这三个都得说出来啊。
我来说两句