00:06
怎么样,想的差不多了吧。这个参数不传行吗?就是刚才下课的时候,有的同学这么这么说啊,就是说在调这个service的时候,这不是会new吗?能不能把这个连接对象在这创建出来,把连接象传进去,这样传给过去的时候,就不不用在这传了吧,他说是不用在这传吗?他确实是不用在这传了吧,在这传进去吗?但是这是单立的,你得考虑这对象只能丢几次啊。你有一次啊,还是不行啊这个。所以这种方式你就不用再考虑了啊,你只要是静态变量啊,或者是成员变量啊,你用再考虑了,这都是单立的啊,所以这传的话只能传一次了,所以这个时候的话还是不行多线程共享一个了吧。是吧,那肯定的。
01:02
嗯,啊。这边呢,一个线程一个连接对象,嗯。就这个版本啊,是不是还没改是吧,没改啊,就是奔这个目标去就行了,那这样的话,在做这个版本之前,我先讲个知识点啊,讲完之后咱们咱们才能用啊,来点右键,咱们新建一个Java项啊,叫thread local。好,现是行了啊,就用它。讲一讲他啊,注意听了啊。Java web啊,我想一想啊,Java web后边的话,咱们给上去一个U吧,嗯。然后这边呢,有一个工具类,咱模拟一下叫DBU吧,DU啊然后这呢,有一个类型,这个类型叫什么呢?Connection啊好,我自己写我自己的吧,这个connection,然后接下来呢,这边呢,我写上写个方法吧,Public study返回个什么connection吧,叫get什么connection吧,好,我们目前的项目来说,只要我们调这个方法,只要我们调这个方法是不是就会拗一个对象出来,是不是就是connection connection吧,可以new一个什么connection吧,啊new出来好直接把这个connection干什么返回我们现在是这么写的吧,嗯。
02:29
那这不是一个connection吗?是我自定义的啊,这个跟那个R跟跟咱们那个叫什么CDBC,呃,跟那个CDBC可没有关系啊,这是我自己定义的,然后呢,这是个工具类,只要教这个方法就会获取一个连接是吧?好,这个准备好,那么接下来我再模拟啊。好,这边呢,咱们写上去,比如说一个service,然后再写一个叫什么到吧,啊知道啊来这个呢,我叫什么service呢。
03:00
我就叫user service吧啊user service finish到呢,我就叫什么到啊。需要U会到了啊,我也不用再什么了,再起其他名了啊,You会到1SERVICE准备好,然后接下来我再来个客户端行吗?我再来个客户端啊,客户端的话,这边得建一个包吧,叫什么client吧,这边再几个类啊叫什么呀?Client啊,So叫so啊嗯问方法行不行,这家能看懂吗?嗯问方法从这进来吗?So叫什么so吧,So叫什么?叫到吧,啊叫到so来叫S叫到嗯。S night。嗯。行吧,这这这个我先删了啊,这个right单独right,然后呢。这边我改个名啊,不用这个名字,我写的稍微稍微那个复杂一下吧,啊稍微复杂点,嗯,这边的话咱们给它改一改啊,不叫client叫什么叫,然后呢,我再来一个包。
04:06
我再准备一个包啊,这个包呢,就叫这个叫client吧,或者是。这叫tomcad吧,啊模拟那写个类叫什么tomcad tomcat服务器启动是不是有问方法呀,问方法啊OK。你看整个程序能看明白吗?这么几个类首先的方法在哪啊,他们看在这吧。嗯,它会掉什么呀。叫service吧,Service叫什么service吧,Service叫到吧,这是不是有工具类,是供我供我们使用的吧,啊这个先不用管,工具类不用管啊。呃,他们开始问方法会掉service,而service会掉service service会掉到啊好,那么接下来大家看一看,这是这边我加一个方法,这个方法呢叫public service方法啊,然后呢,这个方法呢,我就叫做public,呃,VO就叫什么方法呢,就叫。
05:09
用户有相关的业务删除吧,删除用户啊,Delete by ID好,这边呢。啊,就一个比例的方法得了啊,然后这个比例的方法会调什么呀?这个里边比例的,这里边有个比例的方法,这能看懂吧,好看清楚啊,是闷方法调谁service light里边的service service会去调谁service,呃,这个service里边的service方法,而这个service方法会调用,这个叫改成do get吧啊do盖的方会调service里边的delete delete呢会调这里面delete,这个delete返回返回,返回之后呢,给他,然后最后再给他吧,这个过程是不是跟我们那个web项目是差不多的,能理解哈,那我们这这块的话,我就先这么着,大家看啊,它会调serve light,所以这需要serve来对象吗?需要吧,Serve that对象serve light,然后你一个什么serve that吗?这是他的服务器为我们创建的吗?这个对象是单利的吗?单利的对象啊。
06:19
所有线程共享一个吧,所有线程啊,共享一个s swim like对象,那么这边呢,Server对象有了之后呢,我们就可以调用server对象的方法了啊主线程去调吧,主线程啊调用serve light对象的覆get的方法吧,读get方法好那这样的话third叫什么?Do get吧?好,这大家能看懂吗?啊,对象一个do get,那么do get方法执行的时候呢,它需要一个什么。Service吧,那么service是不是也是单立的呀,Your service吧,Your service啊用一个什么your service吧,嗯,Your完之后呢,这个your service调哪个方法呀,叫your service,点什么delete吧,好,那这个delete会掉吗?掉了之后这个delete里边需要个什么一到了一会到啊又一个什么会到吧,好这样的话,这边呢,我们来看一看掉的是一到里边什么方法呀,点delete吧,好,这个delete直行直行会在这这直行好这样啊看好了。
07:30
我这个方法呢,用了一个对象。然后掉了do盖的方法,这个do盖的方法呢,咱们拿一下啊。Thread大家知道线程是吧?线程它好像有个属性啊,或者有有一个方法啊,叫current thread,这个大家知道吗?哎,这个方法可以返回什么当前线程对象对吗?好,那么也就是说它会返回一个thread是吧?Thread啊好,这个thread呢,是一个当前线程啊thread t这个线程能取名字吗?怎么获取名字呀?点get name吧,好,那这样的话你拿的是当前签的名字吧,叫current thread name当前签字的名字吧,好,这个我可以输出这样吧,我写的写的这样啊,写的少一点,我把这个直接输出得了行不行?这句话当我调delete的时候。
08:31
能不能再输出,在掉这个比例的时候,我能不能再输出。好,你看啊,调do盖的吧,Do盖是不会输出当前先生的名字啊,机器本上调比delete吧,比delete的方法会不会出当前先生的名字啊,那掉这个题里头会不会输出当前生的名字呀?诶。这几个数字一样不一样。
09:07
啊。这个线程继续往下调delete的方法,Delete的方法再执行,输出当前线程的名字,再调delete。再输出当前线的名字,所以我问大家啊,这个比delete的方法在执行的时候,线程对象当前线程对象和这个对象执行delete的方法时候,当前线程对象和这个类里边的do盖的方法在执行的时,当前的线程对象是不是同一个对象?就就就是我想表达一个意思啊,什么意思,这个你得知道啊,Do get叫什么,Do delete对吧?呃,错了啊,Do get调delete吧,呃,继续这个delete会叫这个delete吧,那么最后比例子执行对吧?好,这是几个站。一个。我讲过没有一个线这个站的问题,一个站。
10:01
谁在站的顶部?谁在站的顶部,这个方法在在不在站的顶部啊,在吗?谁在站的底部啊,站的底部在哪呢?闷,方法是站的底部,实际上是啊。这个对象这样吧,我我把它为了保证是一个啊,所以这个时候我就给他拿过来private static private啊static这个对象是不是只有一个了,类加载时执行只有一个吗?这个对象。调,这是主线程。主线程,主线程去调的这个方法。整个整个程序只有几个线程啊,一个线程啊,你从这儿是个入口吗?调的是都盖的吗。Do get会掉do delete吧,Delete,这不是会掉这个delete吗?那到最后delete,所以这个在站的顶部吗?所以这个时候大家看一看,这实际上是有个站的。
11:02
嗯,这个希望大家能够理解吧,嗯,这个非常非常的重要,这个东西啊,来首先这边大家想一想,最底层是个什么东西啊,嗯,问方法。是吧,这边我调一下啊问方法,然后问方法先压进去的。焖方法压进去之后呢,接下来。是不是闷方法去掉了哪个方法呀,Do盖的方法呢?所以这就是do盖,Do盖掉了哪个呀?Delete吧,Delete掉了哪个呀,是不是delete呀,所以你看看就出来了。所以这边呢,调的是什么呀,Do get啊,然后继续do get掉了一个delete吧,啊delete delete这边呢,再往下走,注意啊,一点一点看delete再往下走是不是掉了这个delete呀,哪个delete就是最后这个吧,你看啊,这就是那个比例的方法,嗯。
12:05
然后哪个方法最先结束,是不是到先结束,这个方法结束之后,这块内存是不是释放掉了,然后哪个就结束了。Service方法是不是就结束了?Service法结束之后哪个方法结束了?Service方法结束了,Service方法结束是不是那方法结束了?所以我问你这几个方法,只要你这几个方法执行是一定在一个站里边吧,既然是一个站,我问你是不是在同一个线程中。你这个方法问方法调do,盖盖调delete delete调这个delete,整个程序执行只有几个线程个线程,你这几个方法都在几个线程里边,一个线程里边是这意思吧,所以大家看清楚了,这个输出结果和我们这个地方的输出结果,和我们再往上这个地方的输出结果,还有我们这三个,大家看一看是不是都是一样的。我这样吧,我这么着,我在这自己起个县城行吗?
13:00
我起个线程可以吗?我自定义线程怎么自定义class my thad行吗?My thread啊my thread好了去继承什么thread,那么继承thread之后呢,接下来是不是重写一个方法,是不是叫run方法呀?好,那么接下来大家想一想,Run方法这个地方呢?多个线程共享同一个数据的话,大家怎么做的,怎么做?嗯,我有办法啊,我还是给它放到这,放到这之后呢,怎么做呢?这还是那个serve对象啊,呃,Serve对象只有一个,那么接下来我们怎么办呀?在这边我们给一个什么serve that serve that吧,在这给一个public my right构造方法吧,好,我这边写一写啊,大家看这个能不能看懂serve吧,Serve that吧,这写什么this.serve that serve that吧,好,给上serve that好了,那这样的话大家看一看,当我们在这呢创建线程的时候,来在这创建什么线程对象,怎么创建thad t线程,你一个什么MY是不是my thread,这个my thread在new完之后,接下来大家想你new的时候会调构造方法,而构造方法里面需要个thread了,所以这时候把上面thread是不是传进去了,那这样的话,大家看这是不是可以线程线程t1.s内啊,把线程一起个名线程一就叫T1吧,行吗?接下来T1线程是不是可以启动了。
14:30
Start的方法是不是启动啊,点start的方法启动好了,这这个是什么?设置线程的什么名称,接下来这个是设置什么?这是启动线程吧,启动线程哪个方法开始执行,注意啊,占内存分配啊呃分配完毕,分配完毕之后呃会直接调用哪个方法,会调用乱方法吧,乱方法是什么?是在是在哪啊,是在站在什么底部吧,是不是在占的底部啊,那么接下来这个删掉啊,这个删掉,那么接下来我是不是可以把这个代码复制一份,复制一份之后呢?大家看一看上面是不是把这个三又传进去了,这个线程叫什么T2线程对吧?那我设置T2线程的名字是什么T2吧,那这样的话是不是T2就启动了?好,我问你现在的话除了主线程之外,还有几个线程两个,一个是T1线程,一个是T2线程,对吗?T1线程会启动一个站对吗?T2线程也会启动一个站对吗?这两个站是不是不一样的站呀?
15:30
那这样的话,T线程启动之后呢,它会执行这个run方法吧,而我们run方法在执行的时候会调用sorry,里面的方法叫do什么,这大家能看懂吗?这能不能看懂?来,请问我在这加个断点吧,好,我问大家啊,Tnu出来t.set name t.start下面代码还没有执行的时候,我们的转方法是不是开始执行了?因为线程启动之后,Run况是不是就开始执行这个三来是是多线程才共享的一个对象吗?这个扭了几次,一次T1线程和T2线程有没有共享这个对象共享了吧?那么接下来大家想一想,只要你do盖的方法一直行,是不是就开始输出一个线程的名字,这输出是几啊?是不是T1?当去掉底delete的的时候,这个方法输的是几啊?T1对吧?当继续掉底力的这个地方是几啊?是不是T1啊?但是你别忘了,如果这个时候我断点放开的话,它会不会在谬个线程?
16:27
会不会在设置名字会不会启动啊,这个时候是不是一个新的线程,和这个线程是不是没有关系了,那么接下来是不是会掉转啊,会掉do盖的吧,所以这个时候输出是几啊T2接下调这个delete是不是,这是不是T2啊,接来调delete了,这是是是不是还是T2啊,这大家能看懂吗?理解我的意思吧,只要是在同一个线程中。只要是在同一线程中,当前现实对象永远是一个吧?先不用管它点右键啊,Bug运行好程序,大家看看是不是走到这儿了。
17:05
走到这是不是意味这还没有走呢,这个已经结束了吧,你T线程一启动,你看TT是不是三个都是一样的呀,除非你就是再启动一个线程吗?你再启动一个线程往下走,往下走你要start,你一旦start,你看是不是就是都是T2啊。这说明什么问题啊?嗯。这说明什么问题啊?这个名字和这个名字一样,不一样。或者说我们换的更专业一些,这个线程和这个线程,还有我们底层的这个线程是不是同一个线程。也就是说我再换一种写法啊,在这呢,我可以调的select,调这是一个select,点什么?看right吧,这是当前线程,这里边有个线程T对吗?好,我问你这个我也不输出了,我把这个能复制一下放到第二个里边,我再贴过来,我再放到这,我把它删掉,我再贴过来,我就问你吧,这个T和这个T,还有这个T,设三个T是不是同一个T。
18:24
是吧?这不都是当前建成吗?我说过了,方法在调用的时候会发生压站的动作嘛,压进去再压一个,再压一个,你想一想,在在同一个站里边,你知道A方法调用B方法,B方法调C方法,C调DAABCD,你永远掉下去,无限制的掉下去,你再怎么掉,它也是在几个线程里边一个线程中。对不对啊,除非除非你在这儿干什么了,又起了一个线程,又重新调的时候,那肯定是另外一个线程了。但是啊,你只要是A掉的B里面的方法B,如果再往下掉的DC的方法C,再往下掉的D的方法,你只要掉下去,这个线程只有几个。
19:04
这个县城只有一个,为什么?因为他们在不在同一个站中。好,那既然是这样的话,那我问你啊,这个程序就我上面这个m Mac棒个五的话,我们刚才说了要保证谁和谁里边同一个对象。Service和这个到是不是保证我问你啊,Service这个方法只要传一调用,它会调用这个select方法,会调这个方法吧,那我问你啊,这是几个线程。这不是transfer吗?调这个吧,在这个方法里面有没有现成对象,有,那到下边这个方法里边有没有现成对象啊,到这个方法里有没有现成对象,我们你这个现成对象是一个吗?必须掌握一个知识点啊,就是大家能够你别看这个类啊,跨类掉了这个类里面掉了这个类里面方法这个对象掉了这个方法这个对象掉了这个,这个掉了这个传了好多次,但是你要记住它们一定是几个站一个站,几个线程一个线程,你再怎么跨类,再怎么跨方法,你永远这个方法和下一个方法有一个共同的变量,在这个方法有个线程T,在这个方法里面也有个线程T,而这个T和这个T是一模一样的。
20:18
明白我的意思吗?就是说你发现没有,其实我们刚才讲的这个例子啊,他派的服务器在闷方法执行的时候,会创建S小这个对象只创建一次,问方法结束呢,整个程序就结束了,那么接下来会创建线程T1,会创建线程T2,线程T1创建把S传进去,创建T2,然后呢,把这个线把这个S出来传进去,那这样的话,我们就是多线程共享一个对象,启动线程之后呢,我们会执行督盖的方法,这个督盖的方法执行的时候呢,会输出一个线程,这边呢执行会输出线程,这边也会输现,只要你是一个线程里边这个T啊和这个T啊,还有这个T,这三个T是同一个T。你再怎么跨类,你跨100个类,它的气呢,也是什么同一个我们输出看一看。
21:02
来这边的啊,这边的好。那这样的话,我是不是还得加个断点啊,不加断点看不出来啊,加完断点之后,这个线程二是不是不会启动,接着点右键啊,我们第bug运行。你看是不是同一个线程。但是你线程二一旦启动之后来启动。是不是另外一个线程啊,但是你再怎么跨类跨方法,我给你这三个一样不一样这三个啊。这这三个是一样的吧,那再往上这三个一样吗。是不是一样的呀,都是一样的,好,那我问了啊,我不是刚才说了吗?我要完成一个功能,什么功能啊。两个类之间。传递同一个参数对吗?那既然这个T如果和这个T是同一个T的话,我们能不能把那个连接对象绑到T上面?
22:01
能不能把那个connection这个对象绑到T上面,达到两个对象之间的传递同一个参数。我们能用map集合吗?K存什么?K存线程。Y6存什么?Connection。行吗?可以吗?就是你听明白了吗?这有个T吗?是不是有个T吗?在这里不是还有个T吗?你这三个T永远是相同的,对吗?你都错了吗?这三个T永远都是相同的。这仨是一样的,这仨是一样的。你是一个站吗?好了,那么接下来我就来做一下啊,怎么做我准备啊,我刚才说了啊。那这个关掉了。来看这儿的啊呃。
23:01
嗯,现在看啊,这有个DB吗?DB不是get connection方法吗?我们调下这个方法啊,调一下来在这个里边do get我就不再调了啊。调delete吧,Delete是不是会掉这个delete啊,这是哪个方,这是哪个类啊,Service吧,这是哪个类啊,倒吧,注意听啊这边的看好了,我能不能拿这个连接对象。等于什么DB,求点什么get很耐么好,这个我注掉了啊,不再输出了,这个也助掉不再输出了,Serve light这边呢,我也住了,它这个不再输出了,这个都不输出了,然后呢,我继续啊,这边呢我也就不再输出了,这个不输出了啊,但是大家看清楚了,我现在在这个service里边有个connection对象,然后将来我会调谁。将来我会调谁啊?会调这个delete吧,这个delete的方法在执行的时候,我们第一次的时候是不是把这个connection传进去了,如果我传给下一个方法的话,下一个方法是不是在这就能拿到了。那么这个和我们。
24:13
我们现在用的就是这种方式,传单的方式来拿到,拿到之后呢,你在这叫delete,我把这个class创建出来,创建出来之后呢,我把它输出输出啊,输出之后呢,我是不是把这个connection传给下一个方法,下一个方法是不是拿到了,是不是输出了,接下来我来再来测一下啊这个线程。这个我可以住掉了吧,不用起那么多线程了吧,起一个就行了啊,我再运行一下,点右键运行能不能保证一个。可以吗?就是我现在service里边需要连接,因为我要在这控制事物吗?那这样的话,我到道里边是不是也需要连接,那这个时候我是传的参,我说过了,我要达到一个目标,什么目标。不传参了,不传了。
25:01
Delay的方法,这个参数没了。你还得给我保证什么?但是现在保证不了,现在你输出这俩一样不一样。这叫get connection,拿出的是什么?是不是扭了一下,如果这个里边调get connection是不是也拗了一下,所以现在这个程序你看一看点右线,这俩是不一样的。是不内存地址不一样,我们说过了,咱们能一样,刚才也说了,怎么一样啊,是不是传参啊,这个只要连接有了,是不是传给下一个类,这个下一个类是不是就得到保障了,但现在不传了,所以你只要改造哪个方法就行了。这个方法是罪魁祸首,不能掉了吧?是吧,嗯。注意听啊,困的话就暂会吧啊,这个例子你要听不明白后期啊,我强调一下啊,有一个框架叫ru框架,还有咱们后期所有的什么be底层都用了一个东西叫th local,这个th local要是听不明白,这个可能会影响到你整个的学习过程啊。
26:09
那从今天开始的话,咱们就要用local了,你为什么要用的话,这个很重要,现在呢,你必须把这个听明白啊,来这个会service再来捋捋,我讲慢点啊,Service里边控制事物,拿连接。在道里边也需要连接,我第一种方式是什么?是在这儿拿到之后方法传参传进去,传给道,道在这直接用就行了,但是现在我们在这儿是拿了一下,然后到另外一个类里边,在这儿又拿了一下,拿到的对象必然是不一样的,我已经输出了,它是创建了两个对象,但是我刚刚讲过了,你不管是这个类去掉的这个方法,还是这个类继续往下掉的,你们的线程是只有几个的。只有一个线能,所以这个时候我决定在这加一个类,这个类叫thad local啊,我起名叫th local,然后这个th local里边我决定提供一个集合,这个集合是map集合,Mapb集合K部分存线成对象,Value部分存object,那这边呢,我写上去啊,这是一个thad local map这边呢,我new一个什么呢?哈西map thread object,所以这个时候我最好用一下泛型,行了,这边我用什么T吧,这样的话,这个就写成什么就行了,T吧,这写成什么呀,是不是T呀,好,大家看清楚了啊,这个麦的集合。
27:39
K存储什么?当前线程什么对象?Value存储什么?Value存储。和当前线程对象绑定的数据吧,也就是说在同一个线程中传递数据必须得使用这个类型啊,在。同一个线程中传递啊,在同一个线程中传递一个Java对象啊,对象Java对象必须使用thread local啊,Thread local我们说过了,这个th local里边有一个map集合,K存线程value存的就是那个对象,那这样的话,我们在这个里边是不是应该提供存储的方法,也应该提供取的方法。
28:25
对吧,来我们提供一个方法进行存储啊,来S。这个我知道value吧啊存储value,那这后怎么存啊,只要调它就调用这个map集合的一个方法put吧,线程是什么来点什么current来吧,然后这个地方存什么。是不是T啊,是不是value啊,存进去就行了啊,再就是存啊,像当前线程啊。
29:00
或者是向当前线程中啊绑定一个数据。好,大家捋捋这个什么意思?没事儿,我给你时间啊。看好这个K就就就就就明白了啊,看好这个K同志们啊,看好KK是个什么对象。是个县城。把Y6是不是放进去了,只要外部把这个对象串出来,调这个S的方法,是不是就会把它放到这个mapb集合中?好,那我问你啊,是不是应该再提供一个方法,返回方法,而这个方法就是返回T叫get,括号里面什么也不写,直接return一个map集合正号有个方法叫什么get呢?它只要调用这个get方法,它K是当前线程,对吗?这是从什么?这是从当前线程,当前线程中读取绑定的什么数据吧?
30:11
这个现在你可能看不明白啊,但是我解释一下来,我先解释一下啊,这个类呢,我故意起名叫s loo,然后里边提供一个mapb集合,而这个mapb集合呢,我说了它呢有K和value组成,这个K存储的是线程对象,而value存储就是要绑定的数据,刚才我说过了,这个service调service service调到,听清楚啊,我再从这开始讲一讲,Serve调service service调到整个程序执行过程中,他们这三个类,或者说三个对象里边有一个共通的对象,这个里边有个T对象,这个里边也有一个T对象啊,这个里边也有一个T对象,就是这三个对象共通的特征,这个里边T和这个T和这个T是一样的,那既然这三个对象中有共同的对象,那是不是可以考虑把,如果在这个类里边,如果和这个类里边还有这三个类共同想传递一个参数的话,我们可以把这个参数绑到K上面,怎么绑定?在这正好准备了一个map集合,Map集合K存储的就是线程对象,而value部分就是存储。
31:11
绑定的这个数据。给它放进去。哎,那么这个时候大家看我这怎么写,还能new吗?不能了,怎么写,我是不是应该在这加一个thread local,我这个里边放的是什么对象是连接吧,所以叫th local啊好又一个什么th local吧,又一下,然后这个放什么呀?好那么请问现在的话,你这个local调get connection是不是应该从th local里边调用那个方法get吧,而这个get方法来我们这样啊把这个。复制一下啊啊贴过来点。哎,这个词logo写错了吗?啊,这果然写错了RI local,来这个名字改一下啊,嗯,这样的话,咱们这边写叫什么th local,点什么get吧,嗯嗯。
32:10
Local。Location。没事吧?DB thread local thread local。这里面不是有一个方法吗。在这儿呢,是这个吧。盖的啊,掉也掉不出来呢。啊,这边得是心态是。好,大家看一下啊,我调盖的是不是connection啊,拿好我问你啊,现在假设啊。咱们捋捋这个程序contact,它在这会调这个do do get吧,那我们你看do get方法执行,会叫do会调delete吧,那么请问这个delete方法会service执行,而这个比delete怎能会调这个get吗?好,请问这个方法是第几次调?
33:12
现在是不是第一次调的这个方法,第一次调这个方法的时候,那我问你现在调get方法的时候,他会走到这个地方,而这个get方法会从level里面取这个数据,我问你这个叫盖的方法,当前线程。有没有绑定那个数据。没有,是不是拿出的是空值,这是ma的集合,而这个线程是T线程对吗?这个线程是不是就是你的T线程?行,我再说一下啊,这个好难,这个啊,看这个这个啊。线程怎么着,起了吧,掉这个吧,只有几个线程,这个里边一个,然后呢,调do盖的,Do盖的方法往下走,走了之后呢,这有个T,这个先不用管这个助调了啊,调delete,而delete的方法会调用DBU里面的get方法,而这个方法是第一次调用,你想想它会掉,掉的时候呢,它就会从索logo里面调钙的方法,而这个钙的方法拿出的值是nu值。
34:13
所以我问你,你现在这个时候呢,判断一下,如果这个是none的话怎么办。牛不牛?是不是扭出来,扭出来就反完了吗?你要不要调来local的方法叫什么方法?S你把connection是不是存进去好再捋捋啊connection耐返回吧,好,我问大家第一次调这个方法的时候。第一次调这个方法的时候,这个得出的值是不是空?是空的话new吗?New的话是不是就直接存进去了,好,我问你这个S的方法一执行,是不是让当前线程和那个叫什么那个。那个whether是不是绑在一起了,好,那么请问啊,这个时候。
35:01
我们这个方法就返回了一个connection,请问现在执行第一次是不是执行完了拿到这个connection了吧,那么接下来它是不会调delete,毫无问题,在调delete方法的时候,在这个delete方法这个线程T。和这个线程T是同一个T吗?那这样的话,在这是不是会再调DP的get connection方法?在调这个get方法的时候,这是第几次调在同一个线程中,这是第一、二次,第二次调这个方法的时候,该attention方法执行外local在调get的方法的时候。能不能拿出这个value。这一回是不是就不是空了?那么接下来我们再启动一个新的线程的话,调do get 2do get,调delete delete这块拿出的时候,我们是不是新线程,既然是新线程,你该的开始方法就要get的这个方法拿出的这个值。
36:00
新线程嘛,Map集合里边不是由K和Y6组成吗?对吧,K变了吗?又启动新的线能,K是不是变了,K变了,这个value是不是又空了,又空的话。是不是又用了一个存进去吧。存进去之后,你想一想,是不是就相当于把当前线程对象和那个值绑在一起了?其实啊,我就别说这么复杂了啊,看啊,这是个map集合。Map集合呢分左和右,左边是K,右边是value,这样我简单画一下K和value,看清楚啊,它呢是这样做的。第一次访问的时候,他往里边掉了哪个方法put?放了一个线程T对应的一个什么对象啊,Connection对象对不对?那我问你啊,只要在同一个线程中,只要在同一个线程中听清楚了,线程对象只有几个。
37:01
只有一个线程对象对吗?当我们第二次在面向这个map机和调盖的方法的时候,由于你这个方法没有结束,线程没有结束,你这个T永远都是T,而你这个T就是这个T,跟这个没有关系,所以这个时候这个T关联这个对象是不是就能拿出来?你只要是在同一个线程,这个T值有几个一个。当然我问你这个时候如果再启动一个新的线程的话,那个线程可能叫什么呢?叫T1线程呢,那那个时候的话,我问你再调的话,你是不是还得调铺的方法,把这个叫关联的肯定式再存进去啊,那这样的话是不是表示一个线程一个一个线程几个连接啊,一个线程是不是把那一个连接对象。还是那句话,我说一下,这个东西不能写到这啊,如果你把connect项不是这么写的。你是这么写的,Connection?这地方加一个什么static这几个方法,Public返回什么返回connection叫get public static返回get connection,然后这边直接的判断,如果connection要是什么等于等于什么,那然后直接等于now的话,你怎么办?Connect new吧,啊new出来,那这样的话直接最后返回吧,这样做不行,为什么这么做不行。
38:24
这样做会导致所有线程共享几个对象一个。这个类会只会加载几次,一次他们派的服务器不关闭,是不就是闷方法一直执行,而闷方法在执行过程中,这个类已经加载,加载完之后呢,这个声明一次,这个等于空你一次以后都是拿着这一个,所以会导致所有线程共享一个连接对象,这种方式不行,改一改怎么写,看清楚了啊,这边我要写一个方法,返回什么对象,Connection对象,然后呢,我就要get什么connection怎么做的,这边是怎么做的,要注意了。
39:02
首先呢,它是这样的啊,在这呢给一个什么thread local里边存储的是什么对象connection,然后呢,我们就叫thad local,然后new一个th local啊好,我问你new的时候会调会调构造方法对吗?构造方法执行的时候会不会调用我们的成员变量,初始化我们成员变量,所以这个map及合是不是就创建出来了,创建出来map及格之后呢,我们就面向map及格,其实它就是个map集合,而这个map集合的K存的就是当前线程对象,而这个value就是绑定的数据,你只要是在同一个线程中,这个这个这个K是永远都不变的,这个时候Y了就能拿到同一个,如果你在启动一个新的线程的K就变了,如果M集合中K发生改变了,那你Y的话一定是拿不到了,拿不到Y了,就是空拿不到空拿不到Y的话就怎么办呀。就在新建一个连接吧,再放进去吧,你只要是在同一个线程中,是不是就定下来就是T了,你可能是这个map集合,左边是K,右边是VALUE6,那这是T1线程,这是T2线程,这是再来个T3线程嘛,你现在T1线程绑定connection吗?T2是不是绑定connection t3线程是不是绑定connection啊,你只要是在同一个线程中,你想一想这个connection是不是永远是你是你自己的,所以这个时候你想你从此漏点get这个方法,你就可以取出这个connection对象,但是你要记住啊,这个方法会频繁调用,这个方法会被频繁调用,在同一个线程中会调两次,连续调两次,第一次调的时候这个可返回一定是空的,这个值一定是空值。
40:35
第一次调这个方法的时候一定是空的,但是如果要是空的话,你是不是必须把临界对象创出来,你光创出来就行了吗?你光把临志像创出来就可以了吗?你还必须把这个零志像跟这个当前线程绑在一起,怎么绑的?Logo里边有一个方法,这个方法叫side,可以把它绑上去,你只要绑上去,下一次再调这个get的方法的时候,它就一定会拿出这个连接对象,可以保证在同一个线程中传递一个Java对象。
41:04
明白我的意思吧,能不能跨两个对象传出去啊?可以。但是有前提,这个前提就是保证线程,只有线程是在同一个里边。你只要是能在同一个线程中的,我就可以保证在同一个线程中传递一个Java对象。能理解吧,所以这边的话我就存起来,存起来之后呢,这直接就返回谁啊connection吧,嗯,这样好我们捋捋啊好,我问你第一次这个service会不会调这个get方法。调吧,捋啊听清楚啊,来走调get get,而这个刚才调调哪个,虽然logo里面get吧,来找get,好我问你这个get方法里边线程有线程吗?钢铁线程有吗?就是那个线程是T线程吗?好,那我问你啊,调的时候这个M机调钙的方法的时候这个K。不存在。你存过吗?
42:00
没有,你是不是第一次调这个方法,是不是拿出是值,好这个返回是空,接下来返回空值之后呢,大家考虑一下看一下啊,这个是空值。空值条件成立,是不是扭出来,扭出来是不是往下走set了,Set的时候我问你这个值是几。那个线程结束了吗?还是T线程对吗?T线程上绑定了什么数据connection吗?好,绑定上去了,那么接下来这个绑上去了是不是返回了?那我问你啊,继续往下调这个delete的方法,Service调delete delete里边会不会再取这个connection就行,在取的时候会调会掉这个方法吧,而这个方法调用的时候是不是还是执行get的方法,S logo调get的时候,大家看一看这个get里边的调出来logo的那个map的调get的方法,好,我们记得T9了吗?这个题有了吧。哎,不说了吗?那个线程结束了吗。没有线程没结束,这个线程永远是T吧,所以这个时候的话,他就会从这拿这个T所对应的什么connection吧,拿到connection就可以了,所以它可以保证这个connection对象是什么。
43:10
是一个。来这撤销一下,这撤销一下啊,大家看非常巧妙,这个map集合里边永远都是K部分,永远都存了一个参数,叫什么thread.current thad,这个参数它可以获取什么当前线程,你也只要程序在调,调用过程中,这个ad.current拿出永远是一个线程,除非你在底层又启动一个线程,这个变成T线程,T1线程。但是能不能保证这个值永远和这个值是一样的?能不能保证这个值和这个值是一样的,可以保证它俩是一样的,对吧?无非就是你一个线程叫T,另外线程叫T2,那T2的话,这这俩字是不是都是T2,要是T1的话,这俩是不是都是T1。能理解我意思吗?哎,磁六干什么用的呀?就一个作用,听清楚了啊,Logo可以保证在同一的线程中传递什么同一的Java对象。
44:04
底层用了麦的集合,那么接下来呢,大家看一看这边呢,能不能保证我用这种机制啊,先从所面取,取不到就尿拗完存进去,再第二次调这个方法从索里再取,取到之后直接拿,所以大家想一想,是不是只要是一个线程就会扭一次。只要是启动一个线程,这个是不是必然,你有意思啊。所以这就一个线的一个对象啊。一个线程一个对象啊,就是这样。呃,这边我写完这个了,咱测一测吧,行吗?怎么测呀。还输出connection吗?拿到之后输出对吧,来再继续拿到之后输出吧,我看这两个我这次不传参了行不行。运行。
45:06
我把参数隐藏了吗?我当然啊,最最笨的办法,大家必须得会啊,那个办法呀。就是参数传进去。但是我觉得这个参数太累赘。你这每个方法都加这个套,太难看,没有人这么编程,明白吧,公司里面都用哪个叫s local,而且这个类告诉你好消息,这个不用我们写了。这个类散解完了。啊,这个12来看看在哪啊。JDK是你最熟悉的吧,JDK是javas里边的啊,往下走大家看有一个包你应该很熟悉,是核心语言包,叫long包。Long包里边有一个类叫thad,下边有个东西叫th local里边呢,有泛型,看见了吗?它有方法,其中有两个,一个叫set,一个叫什么get get是返回此线程局部变量什么当前线程副本中的值吧,其实啊,你就这么想就行了,它底层就是这么写的,你看我还用的泛型吗?
46:10
嗯,也就是说我问你啊,Lo不是专门为connection准备的吧?我logo里边能不能放一个cat呀?我这个猫呢,想干什么呀?在两个对象之间传递,我又不想传参,怎么做呀?把它绑到s logo里边,就可以保证两个对象中共享同一个数据了。明白我意思吗?不一定非得放,所以我这加了一个泛型,我希望能够理解泛型的意思,就是说你将来往这儿可以任任意传类型,你传一个张三,那你这个返回值就一定是张三类型,你传一个猫的话,它将来返回的就一定是个猫。你这也必须传什么参数啊,传一个K类型能理解了,所以这边呢,我就写个T了啊,写个T这样就是个代号嘛。
47:04
犯刑了,你会用吗?嗯。就这样。那么大家看,人家里边还有一个方法叫什么,We move?好,嗯,跟大家说一下这个remove啊,为什么要用。这样吧,我我我我也加个remove行吗?怎么加public void remove吧remove吧remove,那这个方法怎么写啊。Map集合有的方法是不是就也要remove啊,里边需要K吗?K是谁K是谁啊是它吧,K永远是当前线程吧,嗯,行,这样可以了,移除啊,要解除什么绑定关系吧?啊,解定,解除绑定关系,解除绑定关系啊,这个解除绑定关系我一会儿再讲,现在的话我先不管它,总之呢,这会儿这个程序呢,就完工了啊来运行保证是两个对象接,接下来我变一变啊,这个要求里边变一下吧,这个助调行吗?这一次我用一下S可以吗?S是哪个?
48:05
是Java浪吗?来Java浪啊,好了,这边我再执行一下,看行不行,打开它直接点右键运行。是不是跟我那个一样。我这个啊,讲了半天,其实我就想给大家讲明白一个事儿,什么事呢。A对象和B对象和C对象ABC3个对象中共享同一个数据怎么做?用谁local?但是你要记住啊。共享的这个数据不是什么全局的。只在你这ABC3个对象属于同一个线程的时候,我这个对象才能共享。你要是说跨线程共享的话,这种方式根本就不行。跨线程共享,用哪种方式就行了?两个线程共享一个数据怎么写?
49:02
在这写一个静态的变量吧。Connection只出现几次啊,一次。那是多线程共享吧,这样主要是为了保证一个线程啊,一个线程一个连接。多了一个th local是sun写好的,咱们这边可以直接运行,我这次没有用我自己的啊,我YouTube秀工具类里边用的这个get用的local是谁的,是散啊,这个可以直接运行。呃,大家知道为什么这个不太好学吗?知道为什么吗?有一个知识点,哪个知识点啊,你永远都不好理解哪个知识点啊,A调B的时候,B调C的时候,C调D的时候,你不会认为它在同一个线程中。你会觉得底层起了四个县城。实际上呢,A调BB调CC调B呢,是在什么同一个线程中的,那既然是同一个线程中,你想我给那个mab集合,如果mab集合存这个T的话,你往T上绑一个数据,那当然是可以共享了。
50:11
是吧?Abcd在同一个线程中了。来这边呢,我看一下啊,这个loo呢,我就讲到这吧,嗯,是我们今天最重点的一个内容,也是最难理解的一个内容,这个来lo呢,是完成线程,在同一个线程中数据共享,在同一的线程中,A对象B对象,C对象,B对象在同一个线程中,这个数据共享一份,怎么共享,把它放到一个对象中,这个对象是三提供的叫thad local,它可以完成在同一个对同一个线程中数据的传递问题啊好,那接下来咱们就把这个零五版本改一改行吗?就把这个bank卡啊,银行这个项目改一下,怎么改就改点就行了。
51:10
就改DB是吗?DB怎么改,是不是这个不能这么做了,不能这么干了啊。怎么写,往这加一个什么。这里边存的是connection吧啊local啊,又一个什么local吧,这个静态的只执行一次啊,这个对象只有几个,在整个这个他态的服务器中只有一个啊。只有一个这样的对象,这个map及合也只有几个呀,只有一个啊,这个底层是不是有map及合呀?嗯,有map及合,所以这边呢,咱们就写上啊connection来注意这边呢,我就加上去好了,加上去之后呢,大家看一看这个s local是不是可以在这调哪个方法get这个时候会返回一个什么。
52:03
Connection嘛,但是这个connection有没有可能等于空,如果这要是等于等于空的话怎么办?U吧,U的时候实际上就是这两行代码对吗?是不是新建连接,建完连接啊,把这个去掉,把这个去掉,这边呢给它去掉,去掉之后你要存一下吧,虽然logo点什么带子吧,是吧,Connection存进去啊,这边返回是不是可以了。行,上面两行代码变成下面代码了,从取这个数据。等于空的话,你就扭一下存进去,你只要是第二次再调这个方法的话,来logo调get它取的值就不等于空了,但是你切记啊,这是我说的是在同一个线程中,你要是再启动一个线程的话,那你这个又是等于什么呢?空了,又得新建吧,又得存进去吧,我只能保证你在同一个县城里边。
53:01
这个数据是共享的,你要是跨县能想共享这个数据,这个完成不了。你要说再启动个线程,T1和T2线程,你想一想mab集合这边K还能一样吗?K不一样,Y6能相同吗?是吧,所以这边的话,大家看采用这种方式还是不错的,来接下来我来试试啊,这边是不是service service里边是不是拿了这个connection啊,我们是不是可以不传了,是不是可以不传参了,来参数全去除来又恢复到原状了啊,参数是不是全去除啊,参数全去掉吧,好了,那么去掉参数之后谁报错了接口吧,这块是不是这个参数是不需要了,来这个参数是不是也都不需要了吧?来这边全删掉,那么删掉之后呢,大家想一想,这个实现类是不是就出错出错了。这边呢,你看一看啊,它的时间类是这个吧,是这个时间类吧,啊把这个打开,打开之后你看这个时间类,这里边不是有这么一个参数吗?嗯,参数去掉了啊,这个参数去掉它都不需要了,但是你说你这去掉之后,你想一想下面这个connection是不是就不能用了,嗯,报错了吧,这报错了怎么办?老办法,Connection等于什么,还是等于DBU点盖什么,Connection一定是调这个方法,然后上面干什么,Connection在声明了,Connection在声明啊,Connection等于什么,那么谁呢?
54:23
这次就没事了,来这边呢,我们把这个把这个复制一下啊,你还是拿就行,你拿就行了啊这边connection怎么办,是不是也也是拿呀,滴滴这该什么可能什么你拿就行了,为什么拿没事,为什么呀。因为拿出这个值,还有这个值,你只要是在同一个线程中。我这个connection就是一定是一致的,对吧,所以这边我来看一下啊,只要拿到connection我就输出,我看看它底层是不是一个连接对象行不行。这边呢,我来啊,把这个都关掉啊,关掉之后呢,把这个项目部署一下来部署OK,把服务器启动。
55:03
启动之后呢,这边我们全部给它清掉啊,清掉之后我们把这个给它关了,这个都没有用了啊,这边咱们给它访问首页就行了吧,来这边呢,我就刷新一下,然后这个数据呢,我给恢复一下啊,我看看这个数据来给它恢复一下,选中它执行一个是五万一万好点转账。看底层输出几个连接一个掉了几次。调那个get connection方法是不是调了五次方法,但是这个对象能保证是一个吗?可以对吧?请问这个连接关了吗?我在service里面最后执行结束之后有没有关闭。有没有关闭这个连接,关闭了吧,也就是请问这个连接废了吗。这个连接对象废了吧,但是我问你他和那个线程有没有绑在一起,还绑还在麦B集合里边吗?还在不在麦克集合里边,你虽然把它关了,但是呢,这个失效了,但是你这个和这个线程是不是还是绑在一起的。
56:06
我问你他CAD是不是支持多线程,并且我告诉你一个事儿啊,他们CA的服务器啊,它底层啊,用了一个机制叫线程池,线程池这个东西我简单解释一下啊,那我问你池是啥意思,是一种缓存技术吧,为了提高效率,所以请问用过的线程有没有可能还会再用?他CA的服务器支持多线程,它里边有个线程池,也就是说它拿过线程T1用着用着用着用完了,用完之后它并没有把线程销毁,对吗?他把这线程又重新放到线程池里边吧,其实是一种缓存技术,那么我问你这个时候张三访问完了,T1绑定了一个连接对象connection,最后把连接对象干什么了,干掉了,关闭了,但是连接对象失效了,这个连接对象和这个T1线程还绑在一起,等我们下一个用户过来的时候,这个线程T1有没有可能还会再用?
57:01
线程值吗?线程有可能会被另另一个人拿走吗?拿走这个线程的时候,我们的线程后面绑定的这个对象不是那对吗?是一个已经关闭的连接,对吗?所以这个时候大家看看我试试啊,我第一次再点的时候会不会出错,来我点一下,这是运气问题,大家看啊。关闭的连接对吗?为啥呀?我第一次用完之后,我关了吗。关了,我说过了,关是关了,但是那个map集合里边那个key和value之间的那个绑定关系没有解除,在map集合里边还是有一个T1线程对着一个什么对象啊connect,而这个connect关了吗?是不是已经关了?好,我问你,我说过了T1线程用过,有没有被别人还要再重复使用这个T1?它是在线程池里边,所以这个时候我第二次在房的时候,我很幸运,我又拿到了哪个线程。
58:03
T1线程拿到T线程之后呢,T1线程后边不是空,拿到这个不是空之后拿走连接对象,而这个连接对象是不是已经关闭了,这个时候在掉的时候是不是会报已关闭的连接,那么这个时候大家一定要记住一件事,哪件事儿连接关闭的时候。一定要将它绑,绑定解除,怎么解除local有个方法叫什么remove remove方法就是在这用的。明白吧,哎,这么着吧,我试试吧,这行代码我删掉啊,删掉之后我关掉,关掉之后呢,我把它重新部署一下,然后部署之后呢,这样吧,呃,我我我能不能拿一下线程。我能拿下线程吗?在这个transfer方法执行的时候,我能不能输出线程点看thad吧,好,这是当前线程吗?好,我就输出当前线程啊,我试试我这个线程我能不能重复拿来这边我把它服务器启一下,启一下之后我看运气怎么样啊,这个不一定。来刷新点,大家看看它线程是什么,是不是HP80端口三什么五什么闷呢?好,我问你这个时候我回退一下,这个线程有没有可能再使用点。
59:10
看这个线程,这个线程和上面那个线程一样,不一样。是不是同一个线程,既然是同一个线程,是不是就是T就是没电,但是你别忘了,你一第一个执行结束的时候,这个连接给定关了吗?关完之后你记着一件事啊,你关完你没有把那个K和Y6移除掉,那这样的话,这个这个线程和那个Y6是不是还绑在一起啊,他这个时候下次这个还拿到,拿到就报这个。能理解吧,所以这个时候你一定要走的时候干净点啊,怎么办?一定在关闭连接的时候赶紧移除掉它的绑定关系,你必须移除。怎么移除th local有个方法叫remove,这就移除掉了。哎,但是我也知道啊,有一个这样不会出问题,比如说我在这加个断点呢,我加上断点之后,它是不是就不会出问题了。
60:04
行不行,我试一下行吗?来我再试试啊,点它部署,点它部署来部署OK,把服务器启动来服务器启动一下,启动之后呢,我问你现在加到断点之后,线程现在能重复使用了吗。我在后退再刷新,我再点它,点完之后,您看第一个线是什么。是不是八零杠幺啊好,我问你这回我后退一下子,我或者或者说我再打开个窗口行吗。我再打开个窗口贴过来,贴过来之后呢,我回车,我问你现在我再点一下,会不会再拿另外一个线程啊,这个线第一个线程是不是已经占用了,我这个时候再点的话,他会拿一个新的线程了,不是我点啊,点完之后你看这俩一样吗?这俩线程不一样,所以最后结束之后,我那这俩是不是转账都成功。是不是都成功了,肯定都成功了,这就没事了。能理解吧,我加了个断点呀,但是我要是没加断点,我问你第一次访问的时候很快是不是就结束了,第二次在访问的时候,这个线程是不是拿到了。
61:05
所以你看就会出现这个冲突了,第一次转账是没有问题的,转。转完之后,你看你看拿的什么,拿的是原先的那个那个那个那个那个那个县城吗。妖吗?是不是又拿妖了,又拿妖了,他又去拿药去了。所以咱们得移除掉,这个移除管不管用呢,咱们得试一下啊。呃呃,这个关于连接啊,连接对象和当前线程对象啊,解除什么,解除绑定关系啊,怎么解除,就这么remove就行了,因为这个方法。这边他调的是是不是map集合local是不是map呀,这个map集合是不是调了remove方法啊,一个this这个不用看了,跟咱们差不多啊,我那个写的比较简单啊,我写的比较简单,就是主要是大家理解的关系,行了,这边的话大家想一想,我这个断点去掉之后呢,这个我也不用再打印输出了啊,这个上面这个我也不用打案输出了,那这边的话我就给它关掉啊,关掉之后呢,给它关了,关了之后咱们数据库再重新初始化一下啊,点它选中点它,然后初始化完毕,五万一万把项目再重新部署一下,然后部署之后把服务器启一下,起了之后我们再尝试一下,这边给它清掉,清掉来,清掉之后这边呢,咱们关闭这个咱们后退,后退我们刷新,然后点点完之后好了。
62:35
这边我再点吧,是不是没事啊。哎,我试试啊。我还是应该把那个输出是吧,输出是不是更好一些啊行吧,TH点什么thread.current thread吧,好我再输出一下啊,我试试来,我再清一下子,大家看好了,我这边呢,我点转账用的是哪个线程。一我再点用的是哪个线程还是一,但是我用的是同一个线程都没问题。
63:04
对不对,这是不是同一个线程啊,没事儿。但是连接对象还一样吗?不一样了。就关闭连接的时候,你解除绑定了吗?是吧,就这样,所以今天的任务就算完成了啊,主要是讲一个Mac架构模式,大家呢,以这个棒和五位。最终的版本。然后呢,重点今天下午这个有点难度啊,就在一个知识点上,就叫做re local,大家一定要把它掌握了,它是一个。能够让我们在同一个线程中传递一个Java对象,你不管是跨了100个类还是1000个类,你知道这1000个类在同一个线程里边,我就能保证你这个数据是只有几个呀,一个。因为它底层用了一个什么机制,Web集合K部分存的是什么,线程对象Y6部分存的是什么。
64:02
存的是那个传递的数据。能理解吧,好了啊,咱们今天就到这吧,然后呢,你就把这个东西呢,下载一下啊,第五个版本好好练一下,嗯。休息一下啊。
我来说两句