00:00
好,那么关于同步代码块的这种方式呢,咱们就告一段落了啊接下来的话呢,我们看一看叫同步方法啊,什么叫同步方法呢?诶这块我们就提到了说诶如果呢,咱们啊操作这个共享数据的这个代码呢,我们叫做这个需要被同步的代码了,那如果需要被同步代码呢,就是完全的生命在一个方法当中了。那我们就可以考虑把这个方法呢,比较方便的啊,直接呢,就声明成是一个同步方法就可以了。哎,这个呢,就是咱们对应的这个说明啊,我在这写一下啊说呢,如果。诶,操作共享数据的代码,哎,就是完整的,诶声明在了。啊,一个方法中啊,那么。哎,那么,哎,我们。啊就可以啊将此方法。啊,声明为同步方法即可。哎,方法啊即可行,这个事儿呢,其实也比较简单啊,来我们看看具体该怎么去操作呢,咱们呢,还是以这个实现的方式为例吧。
01:03
Safe是吧,这个呢,是已经是安全了,咱们还从头去拿,我还是从。哎,我先这样,先创建一个吧。这我们就叫做豌豆。Test。给我写个一啊。好好,然后呢,这里边儿的话呢,咱们把呃,上边卖票这个事儿呢,再重新的我粘一下啊。哎,从这到这CTRLC。我就往这儿去粘。把这块呢粘过来。啊,这个呢,我们就把它就去一下了啊。所以这idea你看太智能了,也不好是吧。这个呢,是我们自己的这个TK,嗯。这个呢,我们叫TK1了啊,因为我们刚才呢,这个里边呢也写的TK啊好把它CTRLC。那这个我们叫E是吧。先这样的替换一下。Window test1。Window test1。
02:01
WINDOWS1。I大写。Window。T1。嗯。的上一层。啊,这儿。啊,原来如此,那在这改一下啊。对啊。诶,这调一下。行,我们看一看啊,这块改了,行,咱们先把这个呢,先跑一下啊,先run一下。好这块呢,这不有这个错票啊,有这个重票啊,好,下边我们换一种方式来解决它的这个安全问题啊,在这儿写一下。哎,使用。这个同步方法解决实现啊,Able接口的。呃,线程安全问题啊,有点长啊。
03:02
好,然后这个怎么做呢?诶是这样子的哈,我们现在呢,这个run方法里边呢,写了这么多的这个代码,诶咱们呢,使用的是同步代码块呢来处理的,就刚才已经讲过了,说如果你发现呢,哎,操作这个7K的这个代码呢,完整的生命在一个方法当中,实际上在我们这个题目当中,也就是这段代码。那这个代码,比如我CTRLX了是吧,假设呢,它就完整的生命在了另外的一个。比如我叫一个受方法里边。哎,我就放这儿了,然后呢,在我们这个while这里边儿呢,去调这个收方法呢。那咱们呢,可以呢,把这个方法呢,你用这个代码块包一下,其实呢,也可以比较简单的就把这个方法呢,生明成。同步方法也可以。诶,目前这块呢,有点错误。啊,这个呢,是因为我们这儿写了个break啊呃,因为呢,咱们在这个while里边呢,你可以用,现在你已经把它抽出来了,这呢就不行了是吧。那这个怎么办呢?哎,我这么着一下吧,通过这样的方式我去就是你要简单起见呢,我们直接把它就删掉就行是吧。但删掉的话呢,这个程序呢,就不能自已来结束了。
04:02
那我们就先这样吧,一会儿我来改一改这个代码啊。好,那么这块呢,操作这个7K的这个代码呢,就是123完整的生命在我们这个受里边了。如果呢,按照我们第一种方式来处理呢,其实就是在这加个西这块我们写了个Z,然后呢,把这个数呢给包起来了。这不就还是相当于咱们的第一种方式吗?哎,我们在这儿呢,做一个run。啊,这块呢,跟刚才呢,我们这个同步代码块呢,是一样的道理啊,你发现在这块你看停不了。哎,这个呢,就是因为我们这有一个处没有break嘛。啊导致的啊,那先把这个事呢,我们说一下,怎么让它呢,优化一下呢,可以在这个位置,咱们去定一个波尔型的叫。哎,对,Is flag是吧,这个先让它是个出吧。然后把他那是不是放这儿啊。然后呢,我们在这个else这块呢。把这意思flag呢,是不是改成个false就行。啊,这时候我们再来做一个啊。行,你看能结束了是吧。
05:01
好,那么目前呢,它是一个线程安全的,但是这儿呢,还是同步代码块。哎,我们把它删掉。哎,往前提,现在这个方法呢,里边操作这个代码完全呢,就是我们的共享数据的代码了,那直接呢,就把这个方法呢,加上一个同步就可以了。就是直接呢叫S。啊,完事了。大家注意哈。加的话呢,是挺简单的,问题是加完以后靠不靠谱,这不好说啊,那我们现在去做一个run。那你一发呢,仍然是靠谱的。哎,多运行几次也可以啊,那为什么说这个呢就好使呢,诶或者说这块担心什么呢,还是同步天然器的问题。那这里边儿就涉及到了,那我们这个方法呢,咱也没有显示去写这个同步加然器啊,那这边就提到它是默认的。啊,那么这呢,我们就要考虑默认的到底是谁?对这块我们要说的就是针对于这呢,是一个同步方法啊,如果呢,这个同步方法呢,是非静态的。
06:03
那么这里边儿这个同步监视器呢,默认的就是Z。啊,那对于我们这个方法来讲啊,说此时的。同步监视器。哎,就是Z,那我们这个Z呢,你是改不了的。那我们只能是考虑这个呢,是不是唯一的。啊,是唯一的吗?是唯一的,因为呢,咱们是在这个当前这个实现方式里边写的这个类的对象呢,咱们就只造了一个是吧。哎,所以呢被多个线程所共用,哎所以呢,调用这个方法的时候呢,还是我们唯一的这个对象呢,S所以呢是唯一的。所以呢,这个这次呢这个词。哎此哎这个题目中啊即为S啊是唯一的,那因为你是唯一的呢,所以我们就仍然是线程安全的。啊,就没有问题。好,那么关于这个事儿呢,咱们就说完了啊,那这个说完以后呢,下边咱们就得考虑这个继承的方式,我们看看在处理的时候呢,会不会有问题啊。
07:05
好,那继承这块呢,我同步的也是这么着啊。Window。TEST1哎,这样写的啊,然后这个的话呢,咱们就哎把上面这个。从这。哎,到这儿我们也CTRLC一下啊转过来。CTRLV。好,这个我们叫T1了啊。上面这个window的话呢,咱们也改成叫WINDOW1。CTRL一下。在那儿都调一下。诶好了没问题啊行,那么首先的话呢,诶,我们先把这块呢,给它都先删了就啊。CTRL加L。哎,这个代码的话呢,是有现场安全问题的,先跑一下。你看你看确实是有这个问题的啊好,那么这块呢,我们同步的也来考虑一下该如何去处理啊。呃,首先呢,我们把这个代码跟刚才一样哈,它如果呢,就是完整的生命在了一个诶方法当中。
08:00
所以我们不妨呢,还叫这个收方法啊,我就放到这儿啊,这呢有同样的问题啊。这个话呢,我们把它呢,就也给它去掉,然后呢,跟刚才类似哈,这个位置我们写一个叫波尔类型的。Is flag是吧?先写这个出吧。然后把它呢,CTRLC啊放到这儿。啊,没问题啊,然后呢,这个1FLAG呢,在这儿呢,给大家展成一个。嗯,好,然后这个方法的话呢,我们在事物这块呢,去调用一下。可以吧?可以啊好,其实这块呢,还有一个小细节啊,就这flag呢,咱们也得给它整成静态的是吧,就大家得共用一个嘛。好,这个我就先改了啊好,改完以后的话呢,这块我没有去处理这个现场的安全问题啊,我们先去做一个run。这时候我们发现呢,仍然是存在这种现成的安全问题的,那下边我们就要考虑说这个方法,现在呢,我们如果呢,仅仅呢,是给它加个西红袋子的,说行不行。那这时候你注意呢,它仍然是一个非静态的方法啊,只要呢,是非静态的同步方法,它的这个此时哎,同步监视器是不是就是C啊。
09:10
哎,那么我们说此问题中。啊,或者叫此题目中这个Z呢,它有好几个是吧。哎,你发现呢,就是当前这个类的对象了,这个对象呢,我们造了仨。所以呢,这时候呢,就是诶W1。WR。哎,W3。那既然如此呢,我们要是去执行,这显然呢就不靠谱了。你看还是不安全。不行是吧,呃,那不行怎么办呀。有同学说把这个改成静态的是吧,其实呢,这个不行的话呢,我们只能说呢,这个方法能不能改成静态呢,你得看具体问题了,适合改成静态呢,你就改成静态,不适合那就不要改了。啊,那如果有的方法呢,就是一个实例方法啊,就是里边呢,可能要用这种实例变量了,那就不适合改,那就意味着同步方法呢,就不靠谱啊。
10:01
哎,所以这块呢,就不要刻意的去满足这个同步方法,让它呢能够达到我们的要求,那有的时候呢,这个方法呢,它就不适合加强静态,那你这个呢,同步方法呢,就不太适合去这样来修饰了。那你只能是考虑。就不要这样写了,你不行呢,你就在这里边儿呢,你自己主动的包一下是吧。然后自己呢,指定一个同步加然器是不是也可以啊。比如这块我就这样包一下,然后这个位置,你哪怕你写当前那条class。这样的话呢,才安全是吧,也也就是说呢,你这时候呢,不要刻意的为了说在这块省点事儿,我就写个雌胸寨子呢,说让他安全,这个时候因为这个。同步加湿器呢,是默认的,你根本改不了,那有可能就根本就不能用。啊,这要小心点啊,哎,所以呢,此时呢,我们这个这次呢是他仨诶仍然。啊,是现场不安全的啊。哎,这要注意一下。啊,当然了,就这道问题来讲的话呢,我们要是只是呢,把它诶注入掉,改成个static其实是好使的是吧。就咱们就单独再看一看,就针对这道题来讲,我们就如果我就加个静态行吗。
11:05
哎,可以。那可以是吧,那这种自然而然的你会涉及到,诶,那么静态方法的同步接然器是谁呀。对,这时候呢,它的同步显示器呢,就是咱们说的当前类。啊,当前类其实呢,就跟我们刚才那会儿写的那个是类似的哈,就是window一点啊。哎,咱叫当前类本身吧,嗯,即为。Window。呃,1.class其实这块呢,也是个对象哈。诶,大家不要理解成说这块我是不是写了个类,你要写类的话呢,你就不会写点class了。斜了点,Class呢,其实它还是一个值,其实呢也是一个对象啊,然后呢,因为它呢是唯一的是吧,诶所以这个呢是安全的。啊,单就这个格式来讲呢,是安全的,但是呢,具体问题大家还要看适不适合,要把这个方法加成静态的,不要为了改成前置安全,然后把它加成静态。
12:01
啊,这个注意一下。好,那么回过来这块我们就可以呢,做一个说明了啊,这是我们说的第一个情况啊。然后下一个问题呢,我们提到了这个对于叫非静态的,诶同步方法说呢,默认诶同步监视器是。这是。没问题是吧,啊,对于静态的同步方法,默认的同步显然器是。诶,当前类本身啊。诶,当前类本身啊,就是我刚才写的某某个类点class这样一个格式。行,那这块呢,注意它是默认的,你就改不了了,那至于说呢,能不能用,尤其像这个C啊,你就看它是不是唯一的,还是考虑我们前面这个事儿。这呢我们就说完了啊,哎,那么整个呢,关于继承啊,还有实现啊,两种方式里边的现车安全问题我们就都解决了啊,在这呢,我们稍微写上刚才这个。跟他使用诶同步方法。
13:02
哎,解决。哎,叫记忆成哎thread。累。啊中的啊,线程安全问题啊啊这呢,我们四个呢就都讲了,哎,稍微捋一下啊,咱们一共呢是讲的这四个事儿啊,因为呢,线程的创建方式呢,有继承的。啊有实现的,哎,这样两种方式,然后呢,这个解决现场安全问题呢,我们也讲了两种,第一个呢,叫同步代码块。啊,第二呢,叫同步方法。我们先讲的是同步代码块解决实现的里边的现场。然后又讲了一下这个解决继承的前程。啊,对应的就是我们代码里边的,诶这个呢是实现的,这个是诶集成的啊,用同步代码块来做的啊然后紧跟着的话呢,咱们又讲一下,诶使用这个同步方法。啊,解决这个继承的,哎,解决实现的现场安全问题。啊,这边对应的就是我们这个是解决实现的,这个是解决继承的。啊,这写了四个啊,这个捋清楚。
14:02
啊,捋清楚好,那这个事儿呢,咱们就说完了。哎,那这个说完以后的话呢,哎,咱们回过来整个来看一看,这个叫S这个关键字,它呢,就翻译成了叫同木的啊。哎,那么它的好处是什么呢?毫无疑问,是不是解决了县城的安全问题了?哎,先生的安全问题。好,那么大家想想它有没有什么弊端嘛?看怎么着?浪费CPU资源怎么浪费了?啊,变成单线程了是吧。啊对的啊,诶其实这块呢,我们会发现哈,诶你看我这块说一下,整个呢,这块呢,就是咱们所谓的卖票的这个事儿。带片这个事儿的话呢,本身呢,我们其实呢,是想三个线程呢来做是吧,哎中间的这块呢,大家交互的去执行,但是呢,就是因为呢,这个线程操作的时候还没操作完呢,这个线程你也过来了。
15:03
这块呢,这就构成我们的不安全了。怎么就安全了呢?那你前边的话呢,不管别的代码,你们可能是没有共享数据啊,你几个同时执行无所谓了,但是呢,在执行共享数据的这段代码的过程当中,我们只能是让他一个线程进来,其他的线程都在这儿等着。说白了前面的话呢,你可能是啊,这种并发的也好,并行的也好,大家同时执行的,但是在这个环节当中。一定是一个。是不是串醒的?啊,也就是说只有一个线程。啊,那从这个角度上来讲的话呢,我们这个性能是不是要差一些。哎,对啊,这个没有办法啊,这个就是它的一个弊端啊,也就是说在诶操作共享数据时啊,多线程其实是串行执行的。啊,那就意味着。哎,是不是性能要低一些。
16:00
哎,性能低一些。这个呢,就是我们说它相应的这种弊端。啊,就这样了哈,那以后的话呢,咱们还会学习数据库是吧?诶那其实数据库的时候呢,也会遇到类似的这种问题啊,你想想我们这儿呢,数据库中的一张表,那也有可能是不是好好几个,那咱们暂且先叫线程吧,其实呢,到那个时候我们叫事物了是吧?诶好多个这个事物,或者叫好多个县城都想来读这里边这个数据。或者说呢,来修改这里边儿这个数据,你想这时候呢,是不是会面对同样的问题啊。对,到那个时候呢,我们会专门去讲这种并发问题啊。诶,这个呢,就是提到了叫数据库的叫隔离级别啊,是非常重要的一个问题,而且呢,还会要专门讲各种各样的锁。啊,来解决这样的问题。啊,那其中有一个思路呢,就像咱们刚才现在讲的这个CS一样,怎么办呀,就是我现在这样的一个线程过来以后呢,我现在正在操作这个表中的数据呢。
17:01
你们其他的这些县城,或者叫事务,大家都得在这儿等着。相当于我现在是不是就加锁了。那这个呢,其实就类似于我们的西寨子这种呢,性能是最差的。毫无疑问是吧。啊是最差的啊,诶比这个稍微好一点呢,怎么办呢,咱们可以分的细一点,比如说你这块呢,过来操作的时候呢,你现在只在读这个数据,你没有去修改这个数据。那这时候呢,咱们是不是都可以读啊。反正谁也不改,那读一下能有啥是吧?诶所以这块呢,如果是读的话呢,咱们就不用加锁了,或者你可以理解成加一个叫读锁,读锁呢不影响别人去读。没问题是吧。那时候我要是改,我要我要再写呢。我要再写的话呢,按说就是我现在对这个数据进行修改了啊,我还没修改完呢,正在修改的过程当中,你说别的这个线程或者叫事务过来了怎么办。有同学说那得等着,哎,只要一等是吧,那又是串行的,跟我们CI其实一样是吧。
18:00
那要是不等呢,这块呢,我们可以选一下,说你要么呢,是把我这个写之前的那个数据呢,是不是给返回一下。因为我还没改完呢。哎,本来这里边写的是一,我现在是一呢,我想改成二,二我想改成三,反正我在改的过程当中,行,一呢是改之前的时候的那个数据,那你就先拿着一先走。哎,这呢就是一种思路啊,要么呢,要么你就在这等着。你不能把我这二读出来哈。哎,其实这二呢也能读,但是这种读啊,并发性确实很好。但这个时候呢,其实这个数据呢,我们理解成了啊,以后会说这叫脏数据哈。就是因为我还没改完呢,是吧,我临时正在改呢,你这个数据呢,就不要让用户呢,别的线能看到啊,你要让他看到了,这就是脏数据,我改成三了,我提交了啊,你读个三行。啊,这就以后呢,要讲的非常细的,哎,各种各样的并发问题了,哎咱们就哎现在肯定不能讲是吧?诶大家这块呢,只需要知道呢,我们解决这个方案呢,叫S呢,其实它的性能是比较差的,但是呢确实能保证安全性啊,其实呢,在执行的过程当中就是个串行的,串行肯定不会出现安全问题。
19:06
哎,就这样的一个场景啊。好,那么这个内容呢,说完之后呢,咱们来看下这个课后练习习啊,课后练习题的话呢,咱们在这个,呃,现成的常用方法和生命周期里边呢,有一个题目啊,这个题目呢,我们也稍微的做一下,说呢叫新年的倒计时,说模拟新年的倒计时,每隔一秒输出一个数字。依次呢,输出啊十九八七六四三二一,然后新年快乐。哎,这个呢,好写不?还行是吧,我们就叫做happy newyear。哎,这么着啊呃,这呢,其实他也没有提到,说我们自己呢,去造一个分线程来做了,那不妨呢,我就写到这个主线程当中,其实也行。那就没方法就过来了。啊,那就是到这呢,把这个数呢给它。是不是变立一下是吧,哎,For I一下,I呢,这个值呢,咱们从十开始,这个呢,就改成得大于等于一是吧。哎,减减。这样啊。
20:00
那在这里边的话呢,我们就直接呢,打印一下这个I其实就可以了,但是这块打印的话呢,你得不能太快了是吧。Thread。点I sleep一下,就是一秒钟打一下,这个有异常,我们就在这儿呢,给它一下吧。一点啊。呃,每隔一秒钟,哎,输出一下。嗯,3211的时候呢,这块呢,它会执行一完了以后呢,这个循环就结束了是吧?诶或者这块你把这个零也补上吧。呃,零,然后这块呢,是到一到零的时候呢,你就别让它。我这样写行不行,哎,等等于零的时候。啊,职业这块呢,我们就让他输出一个叫happy newyear。哎,这样是不是可以啊。然后这块你要输入这个零的时候呢,就不要再去执行这个了。我看这块儿稍微的差点意思。呢得往上走。得这么着是吧。或者呢这块呢,你写成if else的时候写这个。李屯有点懵了,这么着?
21:01
I大于零。这儿是吧,然后else。这样行吗?哎,就这样写了啊。好,来,我们做一个re。呀,这个还得等一会儿是吧。那大家呢,就找一下这种感觉吧。嗯。之前有的同学呢,有的同学呢,把这道题做完之后呢,哎,这不可以了啊,来说了一句话,说完之后呢,我就彻底郁闷了。哎,他说呢,呃,学了这么久的Java基础,做完这道题的时候才感觉学Java有点意思了。哈哈。原来前面的都极其痛苦哈。嗯。还有更郁闷的啥呀?啊,学的还没有感觉啊好吧,嗯,学Java的话就这么个点啊,就是大家呢,呃,就感觉呢,前期学的很多东西呢,都不知道怎么用是吧。不像你学前端啊,学这填报啊,你第一天上去呢,你就极有成就感。
22:02
因为原来的话,你光天天用这个浏览器,你也不知道里边怎么做的,第一天呢,给你讲一些标签是吧,写了俩标签,然后诶运行出来效果了,你发现呢,竟然自己都能开始写这个浏览器了是吧,写一些具体的代码了,感觉很神奇是吧。哎,就是所见即所得,所以学前端的话呢,它的这个坡度呢,就非常的平缓,诶这样的上来啊。嗯,其实呢,咱们咱就商务呢,开的这几个学科来讲啊,其实的话呢。诶这呢,假的都是这个起点啊,大家都是零基础的,然后这个呃,六个月之后这个端点这块其实差别不是特别明显啊。可能我会觉得说大数据的这个level更高一些是吧,Java呢,其次前端呢,再次其实呢,这块呢,咱们现在这个课程又更新以后,前端呢,原来讲五个多月,现在也讲六个多月了。东西呢,现在也很多,为啥呢?因为大家都开始卷嘛,是吧。啊,你不卷我就卷你是吧,不是你死就是我亡了吧,大家开始卷,所以呢,这块内容啊,其实讲的都越来越多了哈,只不过怎么着呢,其前端的同学呢,他是这样子的啊。
23:03
他是这样上去的。就是前期的这块呢,它其实诶特别的坡度很窄,很很平缓哈,诶你学一些标签呢,他就觉得诶很好理解一点点上去的,诶Java的话呢,假设咱们理解成是这样上去的。那大数据的同学呢,可能就是,呃。就就这样上去的是吧。其实区别也就在这儿啊,比如说呢,学大数据的同学呢,学到都后期了,前期的话呢,没有任何的效果,像Java呢,最起码咱们学第二个阶段的时候呢,咱们也开始去讲这个ATM是吧。啊,讲这个GS是吧,讲这个后边这个view。哎,这就前段学的这种框架了哈,就能做一些效果了啊,那咱大数据的同学呢,比较郁闷了。就各种还是很抽象的东西,然后呢,学到后期的时候整了半天,最后终于咱们这个呢整出来了啊,那就是我们看到一些日志文件了。是吧,诶这是看到这个日志数据了,这个呢,就是咱们这个终点了,当然了,顶多呢,就把这个日志呢,我们在使用相关的比如HR等等的展示一下,大家看看这个数据的一个展示效果没了。
24:04
啊,不像说Java一样的,似乎说诶我们这块呢,这个数据过来了,后台这块业务呢,咱们这个业务呢,好还好歹啊稍微的还有点儿感觉是吧,大数据的话呢,感觉就偏抽象一些。现在你要说大数据相关的框架就多难了啊,多的多吃这个智商了,其实也没比说Java呢,它就难多少。啊,其实是这样的啊。OK,就是偏抽象一些啊。好,这个我们再拉回来,这道题呢就过了,然后接着看这道题啊。诶,这里边呢,说关于thread sleep的一个面试题啊,说如下的代码当中的sleep执行以后,到底是哪一个线程进入了阻塞状态啊。来,我们来看一看。这,那是一个继承。啊,这呢是一个run,嗯,打印这样一个数据,这呢比较清晰,好回过来在这个main方法当中。哎,造了一个现成的对象啊,起了个名start了,这块就执行这个方法了,然后在这儿有个sleep。
25:01
哎,五秒以后呢,执行,他说这块呢,到底让谁sleep了。哎,是主先生吧。啊,T加sleep对他点。是朱先生吗?哎,我要运行的话呢,看到什么样的效果证明就是主线还是分线场。嗯。你看我一下。然后五秒以后。验证执行的是吧。哎,这拿谁执行的?哎,主线程是吧,对,就是这块,你通过这个T呢T,诶虽然说它是一个线程,但是你不是说哎就是线程,哎去调sleep了,这块其实理解成还是按个对象去调的。比如说我们这个代码的执行,你不还是在这个主线程里边调的。啊,就这呢,其实理解成还是个对象调到他。OK啊,行。好这呢就是它了,然后呢,咱们再来看一下这个,呃,下边这块啊,下面呢,这有一个练习题。
26:05
啊,这个题目。这个题目呢,有限制安全问题,然后我们再解决一下啊。现在有两个储户分别呢,向同一个账户呢,存3000块钱,同一个账户。所以这这是共享数据,每次呢存1000存三次。诶,每次存完以后打印账户余额,诶问是否有现场安全问题。啊,注意啊,咱们如果是多线程问题啊,是多线程一定会有现场安全问题吗。对哈,诶是多线程问题呢,不一定有线上安全问题,比如说你这是一个账户,然后呢,你这个线程呢,操作这个账户的钱,然后呢,这是别人的账户,别人的线程呢,去操作人家的钱,这不就没有现场安全问题吗?对安全问题呢,就来自于呢,是一个共享的是吧数据,然后呢,多个线程来操作的,这就有现成的安全问题。OK啊好,那这个时候的话呢,我们看看这个题目呢,该如何去解决这个呢,我刻意的就写成一个继承的方式。
27:06
咱们看这里边呢,我们同步代码块也好,同步方法也好,这个同步然器我用这次看靠不靠谱。来开始了啊,这呢是关于我们这个账户的一个测试,然后就这样写了。好,这里边儿呢,涉及到了两个储户是吧,那不妨呢,我就用class假设呢叫客户了。让这个customer呢,去继承thread。哎,大家下来的话呢,你可以用一些实现的方式来做一做啊,或者用继承了。那技能的话呢,咱们提到了,说大家呢,得共用一个账户啊,这个账户的话呢,怎么体现共享呢。对,大家可能会想到静态,其实的话呢,我们要不用静态的话呢,也可以。你看我怎么办啊,我现在声明一个class,我就叫做account。这叫账户。诶这呢叫账户啊,然后账户里边呢,有private,诶W类型的叫balance余额。
28:06
诶这呢叫余额,好,那这个呢,咱们先放一放啊,一会儿呢专门来设计它说呢,在这个客户里边呢,声明这样一个属性就叫做account。哎,我这就不把它写成静态的了,那能不能保证共享呢?哎,那就取决于你构造器呢如何去使用了,是吧。好,那么这时候你看我去声明这个构造器啊。这呢,我就声明是account。然后呢,通过构造器呢,我们把当前这个属性呢,给实例化一下。然后呢,你看怎么保证说我造两个customer,大家是同一个account呢。对,你就只有一个给他传进去不就行了吗。啊,你比如说我们这儿呢,有个account。账户是吧。哎,这么着,然后呢,接下来我去这个customer的时候呢,我把这个act呢给你传进去。诶穿进去这呢,我们创建一个customer。
29:03
啊,然后再复制一份,这个叫二。哎,你看这时候呢,这两个俩对象或者叫两个线程,它其实不就是共享的同一个吗。诶,就这种思路啊,这个大家呢体会一下啊,以后的话我们就可以使用这种思路啊来解决问题了。好,呃,那么这块呢,我们是用的这个,你还得给这个线上呢去起名,嗯,你可以用这个构造器或者的话呢,哎,我也可以呢,在。提供一个重载的啊,你比如说在这个位置呢,我们再来一个四针形的一个内幕。哎,咱们在这个里边呢,它不有个构造器,就是起名了吗。哎,我这样不也行吗?哎,这样要写完之后呢,其实你就可以用我们刚才说的这个构造器,比如说这个人呢,叫甲是吧。哎,这个呢,叫乙。哎,这样,哎,我就通过这个勾搭器的方式呢,给这个县城呢,其实把名字呢,还得给起好了。嗯,完事了啊好,那么下边我们看一看啊,要做什么事呢?两个储户呢,他要存钱,哎,那我们要在这个润方法里边呢,去做这个事儿了,所以呢,你要重写这个run方法。
30:08
啊在这写啊,嗯,他要存三次是吧。哎,那我们这块呢,就写个for循环,这个呢,来一个三。诶存三次相当于呢,我们就是操作这个账户的这个余额,让这个余额呢。啊变成了,呃,就是三次增加是吧。加钱的这个事儿呢,我们其实可以定义在这里边。以前咱不也这样做吗?他们那个word叫deposit是吧。哎,这个呢,就是大部型的一个。这样啊,比如判断一下啊,这个它呢得大于零。然后呢,这个当前的balance呢,加等于这个amount。在这呢,就是加钱了,加钱以后的话呢,我们在这写一下啊,说thad.current th.get一个name,比如说这个甲是吧,哎,存钱。哎,存钱,比如说这个存钱1000块是吧。
31:03
哎,存钱1000块,然后呢,余额为,诶这块我们再把这个balance呢给他打印一下。哎,就这样一个场景。好,然后呢,这个方法的话啊,我们在这个for循环里边呢,我们去调一下它呗。哎,我们这呢,就通过这个A点,我们去调这个叫po,每次存1000块存三次。没问题是吧。好,这个事儿的话呢,我们就写好了,如果存的话呢,你希望呢,稍微的慢一点存你这块呢,可以呢,给他再加一个sleep啊。那这个我暂且呢,比如说就先不加了。哎,当当呢,调run方法的时候呢,我们就调这个for循环了啊,就执行它,然后它这块呢,就来调它。啊,没问题。行,然后我们这块呢就来。执行一下啊。哎,首先这个一调,这个叫start。哎,这么着啊,复制一份。定的是二了。好,那么现在呢,他调这个start呢,各自呢就执行这个方法,各自呢去存钱了,我们首先啊run一下。
32:05
哎,出来了啊,出来以后的话呢,我们看这个有没有什么问题啊。他呢存了1000块钱,就是你这个上来呢2000,其实这块应该是甲先存的,打印的晚了点是吧。目前来看的话呢,似乎也没啥问题哈。哎,都很正常是吧,哎,那这块我们说能不能演示一下出现现场安全问题呢。啊,那这里边儿我们要考虑共享数据是谁是吧。实际上就是操作这个钱数吧。诶在这块,比如说我们加上一个。哎,比如上这个一毫秒吧。哎,做一个开啊。好,然后呢,我们这时候再去做一个run。哎,大家看啊。这个问题呢,是不是就出现了?说那甲存了1000块钱,诶他怎么一上来就2000呢?对,当然有可能说他来打印的时候他晚点,但问题是这个也是2000是吧。
33:03
啊,这块你看的话,这不就出现这个问题了啊,这个存完之后呢,直接就成了4000了啊。这不就是线上安全问题吗?啊,那要解决怎么办?诶,这时候我们发现呢,这个balance呢,就是我们所谓的共享数据了,它直接呢,就把这个操作呢,写在这个方法里了,诶我现在能不能把这个方法呢,就加上。能不能用它。对,能不能用呢,取决于这个this呢,是不是唯一的。哎,是不是唯一的呢。哪位同学会想说你这是继承的方式,继承的话呢,就不唯一。对,你得具体问题具体分析啊,不要记这个继承的方式不唯一,而就应该记呢,是不是唯一的,你就看这个对象了啊。它呢,代表的是account的对象。二哥看看呢?咱们其实就造了一个是吧,所以呢,这时候呢,就是我们这个act啊。
34:02
那既然是AT呢,那就是是。唯一的是吧。好,那既然是唯一的,那它就安全。你看这时候我们再去做rap。啊,这个假的就全存了是吧。哎,就成这样了。哎,这就安全了啊,这个为啥甲都一下都存了呢。凑巧是吧。哎,你看甲这块握住之后呢,他存完了,存完一个下一刻呢,是不是又又让他抢到了是吧。对这块呢,其实你要想体现一下有一个交互的话呢,你就在这块你处理一下呗。是吧,它循环的时候呢,你别让他马上抢着,你让他这块睡一下。啊,Sleep一下这个来一个比如十毫秒。1.print啊哎,这时候的话呢,是不是甲呃,抢到之后呢,然后接下来乙就有可能抢到了是吧。哎,这不就有点儿这个交互了吗。嗯,OK啊行,总之的话呢,我们这个结果呢,你会看到是一个线程安全的。
35:04
啊,就完事了啊行,那关于我们这个线上安全这块呢,对应的课后练习题咱们就说完了。OK啊。
我来说两句