00:00
接着呢,我们来看一下使用future和sli local来组合管理这个事物啊,S local大家可能没有怎么太了解过是吧?那我们先把这个local啊,先讲一下threat local的使用啊,啊,这变成三,咱们先把这个学一下,那local能干嘛?我们来看一下文档啊,它是JDK当中提供了一个呃,用于解决线程数据安全问题的一个工具类啊,那我们看一下。我们打开这个GDK啊,在索引这边搜索一下。对吧,Select local好,打开了,来再来看这是一个类吧,啊,一个工具类啊呃,然后呢,我们看看它的一个说明,他说该类啊,提供了线程局部变量,哎,这些变量呢,不同于他们的普通的对应物啊,因为访问某个变量呢,要通过什么get set方法啊,那么每个线程都有自己的一个结构变量,那么它独立于变量的一个初始的副本s local啊,实例通常是类中的private sta字段,那么他们希望。
01:20
将状态与某个线程相关联。看见吗?哎,例如是吧,下面有一段代码,哎这段代码呢,就是一个local做初始化的,这是这是初始化代码,这是一个使用啊使用。然后呢,最后呢,告诉你每根线程都保持对齐,线程局部变量副本的一个演示的引用啊,只要线程是活动的,并且l local实例是可以访问的,诶那就可以用,然后呢,线程消失之后啊,其线程局部。实例的所有副本都会被垃圾回收是吧?那咱们这十类local都讲完了。
02:00
是不是感觉这个文档看的不太好理解,不太明白是吧?来咱们用一些干货对吧,简单的把它汇总总结一下吧,那local是干啥的呢?大家注意看啊local。的作用就是它可以,哎那么解决。什么呢?多线程的数据。安全问题怎么用啊,有什么作用啊,它怎么解决的呢?来咱们来看一下哈,Select local它可以。它可以给什么呢?当前线程A可以给当前线程关联一个数据括弧,大家注意啊,这个数据呢,可以是变量,普通变量啊,可以是对象,也可以是数组集合,都可以记住了啊,它可以给当前线程关联一个数据。
03:09
哎,一个数据这样呢,就避免其他线程访问到这个数据,就可以简单有效的避免了啊,那么对于它的这样的一个使用啊,我们还可以汇总出以下几个特点,咱们说明一下哈,就led local的一些特点就是什么?就这么说呀,还子可能觉得抽象,那我再具体化一些,大家看啊,Select local可以为什么呢?哎,当前线程关联一个什么呢?数据,那么其实这个你可以理解,为什么呢?注意看啊,它可以像map一样存取数据,只不过呢,T为当前线程,你可以这么简单的理解。啊,你可以这么简单理解,大家记住啊,就是每一个线程都可以为自己绑定或者关联一个数据啊,所以我说的是当前线程是吧,每个线程操作它,那么这个线程就是谁,并且。
04:08
第二,大家注意看一下哈,那么每一个记住啊,每每一个local对象只能。只能为当前线程关联,记住啊,关联一个数据啊,如果要为当前。线程关联多个数据,那么就需要使用多个所的local对象实例,记住啊,你要是要关联多个数据,你就创建多个select local,然后第三每个你看啊,每个select local对象实例定义的时候一般都是static类型,一般都是static类型啊,基本上都是static的,第四的local中保存的数据。
05:12
保存的数据在什么东西呢?在线程,呃,在线程销毁后,会由会由GVM就虚拟机啊自动释放。混油虚拟机自动的释放,这咱们了解一下,这就是local的一个特点,当然这么说呀,可能大家还是会觉得老师还是觉得有些抽象是吧?来,那我们具体画一下,我们具体画一下给大家示例几个,呃,首先。我们在这里面啊,写个测试,嗯,我写在哪呀,我写的这个champ里面吧。写在这个里面吧哈,咱们这是用来做实验的嘛,呃,在这里我们再写一个包,com.at硅谷点select local啊。
06:07
好,然后我这里呢,写个类叫做local。Chest是吧,然后在这里面想要这个测试,大家注意看着哈,看几个点。看几个点我们说。大家注意看一下哈,Led local。可以为当前线程关联一个数据,那么简单点说就是它也可以像map一样存储数据是吧?那我们先用map来给你演示一下map是怎么传的,然后再换成它,它又怎么做啊,注意看。Public static。叫final吧,Final static,然后map,呃,叫做什么东西啊,叫做street,然后是object啊,叫做叫做state,数据等于new。
07:06
肯,Colin的还行卖。等于con哈希map。扭一下。好,这就出来了啊。哎,这有啥问题啊。Itll。它的实现类呢,我看一下。啊,肯卡的哈希map,来,我把它给还了。Current他map。这个呢,大家注意啊,它是一个线程安全的map。啊,在高定方向使用的,如果说这个你不会的话,你也可以用一个叫做哈希table,还记得吧,这些都是现在安全的啊,这些都是现场安全的,好,那我用这个吧,这个大家可能学过是吧。
08:08
来,然后大家注意看一下哈,现在呢,我在创建一个类public class,叫做。Tank。Task,然后让它实现randomable接口,实现线程嘛。然后呢,给他创建这个乱方法,我们在这里面干什么事情呢?我们先说明一下哈,就在。Run方法中。哎,随机生一个变量,这个变量呢,就是线成要关联的数据啊,随机生成的,然后呢,一当前线程名为K。
09:00
啊,保存到map中,保存到map中,然后注意看啊,再看,在乱方法快或者说是结束之前,以当前线程名获取出数据并打印啊,查看是否可以什么呢?取出操作就这么简单,并没有什么呃,复杂的操作啊,那在这里面我们就给它生成一个随机数,怎么办呢?要有个随机数对象,呃,Private private static random是吧,等于new random,好。那么这个地方大家看一下哈,london.next。Int咱们给它取一个值范围1000 1000是什么呀?就是取零到999的随机数,好好,那么我们就取一下。
10:05
In,大家注意看着哈,并且呢,我取一下当前线程名。要get啊,Threat吧,点can get name,这个是获取当前线程名。获取当前线程零好了,然后呢,我们打印一下哈,打印一下一会呢有记录咱们得,咱们就可以知道谁跟谁来。咱们说线程多少多少。然后生成的随机随机数式是吧,可以记录一下,免得一会儿忘了,然后保存啊,怎么保存就是map.put大家看一下,这是date是吧,叫date。
11:09
date.put然后呢,Key是当前线程名值的,就是这个数据生成的好,保存好了以后啊,我们做一些工作啊,这个工作呢,我不知道你要干啥,我就让他睡一会儿,让他耗时一段时间就行了,对吧,五秒钟呃,来对他进行出开。好,OK,然后呢,在线程快要结束的时候,再以当前线程名作为T给它取出来。大家看啊,这个代码没有什么难点吧?呃,就是date.get name。好,我取出来了啊,取出来之后呢,我们打印一下,咱们说在线程多少多少,我复制这段。
12:02
好。在线城快。结束时。取出。关联的数据式是吧,然后给它取出来O好了,这代码其实非常简单啊,没有什么复杂的,看见了吗?我就说成个学习数,再取个线程名对吧?然后呢,我让这个线程名和这个数据不就形成一个对应关系吗?这不就做了一个关联吗?关联之后我的结束再给它取出来,没有干什么取分复杂的哈,然后我写个main方法。好,然后在这里呢,创建几个线程。哎,这几个键成int I等于零,I小于三,把I加加好,然后new这个threat里面是a new。Pass是吧,点star这就开启了一个线程了啊,这个呢,它用不了是因为什么呀,这是static,呃,这个呢,它不是给它加上吧,这样就可以用了啊。
13:08
好,那现在呢,大家看一下啊,我我负循环,我开启三个线程,那一会呢,每一个线程啊,都会生成一个随机数进行绑定啊进行绑定,那我们来看看这个效果。我运行一下。大家看一下哈,每个都算成他自己的随机数不同,那么等了这个五秒之后,它取出来的是不是也一样啊,零是889,零结束的时候取得889对吧?二呢是580,结束的时候还是580,一呢是319,你看结束的时候是319。没有问题的,不管你不管你这个操作执行多少次,只要它跟这个线程关联的是吧,你看做一个对应关系,做一个对应关系之后永远都能取出来啊,再试一次。一会儿我们可以把这个时间调短一点啊。
14:03
好的来看第二次还是实验还是一样啊,就4720是吧,04721呢5111呢5112呢149,你看二还是149没问题啊,这就做了一个简单的对应,或者说是关联的。哎,关联了,好了,那么大家注意看一下哈,如果说我们说中间做一些操作,那我们就实际给他做一些操作吧,怎么做呢,我给你模拟一些代码,大家注意看一下哈。我现在在里面加一些类。叫做order service,好,然后这个order service里面它有个方法啊,叫做public order是吧,创建这个订单。好,那我们打印一下,那么他创建这个订单的时候啊,大家注意看着哈,在这里面它需要取于s local当中,这里面当前这一个线程里面保存的一个数据。
15:05
它需要取这里面保存生成这个随机数,它怎么取啊,注意看它在这边,Select local.can get name,先获取当前现存名是吧,然后就开始取。怎么取,大家看着哈,当前线程中保存的数据是加上。什么东西啊?Select local chest.date.get你看我以当年先能领取。我们看看能不能取出来啊,这个是all service。我们看能不能取出来来。我在这里啊,现在执行这个操作啊,我就说new order service.create order,咱们看看能不能取出来啊。走。稍等一下。
16:04
好,大家请看一下哈,零里面是128哦,这这里面没看出县城名是吧?啊,我打打印一下哈,看不到就没有效果了,呃,当前姓程。加上现长名啊,来吧,再来一次。走。我把其他的关了啊。那么大家注意看着哈,那么线程零里面用这个866生成的是吧?然后呢,线程零里面service里面取出来是不是还是866啊,截的时候还是866,看见了吗?你这里面干多少事情不影响它在当前这个线程里面取啊,然后再来看线程一里面取的是呃,八零,然后在这个线程一里面O的service里面是不是还能取出来这个数据啊,然后在这个线程它结束还是取八零是吧?在这个地方868,你看在这里呢。
17:05
868都切成二,都切成二,在快结束的时候,线成二是不是还是868,你看到了吗?这个你在这个线程里面执行多少代码,只要还是这个线程执行的,你都可以随时取出这个数据来,甚至我还可以在这边再加强一些代码啊,比如说我我再来一个叫all DA是吧,我在里面再写个方法,然后叫做public。Want'safe order,好,然后他们俩干的事情一样啊,我在这边还是干这个事情。走,我在DAO里面,由于某些原因,我也需要select local当中保存的当前这个数据。啊,这个数据,然后我在这边再打印一下。
18:02
New order的da.safe的,大家看一下哈,这个数据呢,可以一路传递到这个线程里面去是吧。我们在这边实验一下。啊,这地方没改是吧,这应该是O的do,好,我们再来一次。好。大家看啊,这个代码层级也不会影响这个线程数据的传递。呃,星程一。它关联的是592,你看这个service里面1592没错吧,DAO里面1592结束的时候,线程一结束是592。那么二生成的是770,在service里面,你看啊,它取出来还是770,在DAO里面,R取的还是770,线程结束的时候还770,看见了吗?那零呢,生成的是284,呃,Service里面是284,在DA里面还是284,在线程快结束的时候还是284,看见了吗?哎,只要是我当前线程。
19:06
关联的这个数据。啊,不管你的这个代码层级调用有多深,它是不影响这个数据传递到这里边的任何一个代码去获取的,好,那么接着我们来看一下哈,我们说过sli local呢,它也可以实现这样的一个数据关联的效果,来我们看一下,那如果换成s local怎么做呀,Public static threat local用下面那个哈,大家注意看这里呢,只有一个泛型,这个泛型就是。蛙这个类型为啥呀,注意看啊,New local。因为我们说过啊,这个local呢,它存的时候大家注意它的key是它自己的线程。K就是他先当前那个线程,它跟当前线程做关联啊,你就不需要再传了,上面这个呢,你就不需要用了,你可以换成select local。
20:07
啊,那怎么用呢?用法区别不大,在这个地方local.said就行了,看见了吗?你只要把这个值放下就行了。大家可以自己。大家可以自己刚刚看到那个提示啊,看那个提示对吧,它就跟这个线程局部变量做了一个,呃,存储关联,那咱们把这个I就放进来。那我在取的时候呢,我的取也换了一下啊,我的取也换了,就变成object o等于local.get大家看见了吗?Get,那么我的思维是DAO。要取的时候大家注意也换掉,我连行程名都不用取了,我就不用那么麻烦了,呃,这行程名我还是要打印一下啊,但是我这里取我就不用了,换成叫做select local get就行了。特别简单,操作比原来要方便啊,然后呢,这里面行程名还要打印呢,当我这个数据获取的时候点get。
21:09
大家看一下哈,换成local,它同样可以达到这样一个效果。好。我们来看一下哈,是不是一样的值啊,线程一里面是122啊,那么这个SERVICE10122 DAO里面一还是122,一线能结束时122看见吗?没问题,零是468,呃,Service里面还是六八。零啊,那现在DAO里面零还是六八,结束的时候还是六八,看见吗?二是850 service的二是850 DAO的二呢。呃,还是850结束还是850,你看跟原来效果是完全一样的啊,所以我们说注意啊,Select local可以为当前现成关联的一个数据,你看这就关联上了。
22:03
这就关联上了,它就可以,诶这么一保存,我当前这个线程,我随时要这个数据的时候,你看我只要调用get,在我当前的线程里面调这个get,它就能取出来,任何地方啊,在任何地方都可以好。呃,第二个是什么东西呢?它只能关联一个数据啊,那记住它只能关联一个数据,那如果说我做一个简单的实验,我现在把这个代码写一下啊,我把下面的注掉。哎。斜杠星。诶出来了是吧,这自动补全了,好那么大家注意看一下,如果说我这个select local,点我一次我set ABC这样一个值,然后我在s select口点set另一个值叫BBC,那么我取出来是谁呢。
23:01
大家注意看啊,你只能存一个数据啊,你存多了那没有用,那不管。好,最终取出来的时候大家注意都是BBC。它以最后这个为准啊,呃,不管你是多少个线程啊,不管你是多少个线程,呃,来吧。简单一点,大家看见了吗?每个线程取都是BBC,因为大家看都做了两次操作,只要你set两次,大家注意它就会把原来的值给覆盖掉,所以这个东西里面只能存或者说关联一个数据啊,记住啊,只能关联一个数据,你要关联多个数据怎么办呢?你就你就这么写啊,在这边再来复制一下,咱们就叫local找二是吧,就这样子,那么你可以在所LOCAL2里面保存它。各保存一个数据,然后取出来的时候呢,这里加个R就行了啊就行了哈,一定要记住,稍等注意看,看见了吗?呃,每个线程都取他自己的数据是吧,一个ABC一个BC啊,你要记住啊好,这个咱们也了解了,我把它删了啊。
24:11
OK,还有这个第三点是什么?这个对象实例啊,一般定义的时候都是static,这个比较简单哈,啊比较简单,你看我们定的都是static吧,其实文档中也是这么说的,看见了吗?这个实例通常是static的。啊s select啊好,那第四点我就不给你演示了,对吧,因为这个是你只要这个数据不用了,性能销毁了,虚拟机会自动释放啊,这个咱在这里就不演示好,这个呢,就是local的使用,哎,Local的使用啊。
我来说两句