00:00
各位同学大家好,刚才呢给大家介绍了线程池的概述,包括它的架构,那下面呢,我们来介绍一下线程池到底该怎么去用,首先咱说一下线程池有哪些分类,我在这里边呢,给各位列了三个最常用的分类,那我们先看一下,然后一会儿咱用代码把它做个演示。那我们来看一下啊,首先里边的第一个分类,咱们通过这个叫exec excuses。就是我刚才说那个工具类,然后它里面一个方法叫这个new fix th。里边加个参数是个int类型,那这个什么意思呢?它就表示创建一个线程池,然后线程池中呢,有固定的N格线程,你可能是五个,可能是十个,可能是20个,所以这是我们的第一种方式,也就咱们通俗说的一池N线程,那这个什么意思呢?给大家举个例子啊,首先线程池有一个典型的实际场景。
01:08
不知道各位同学啊,是否去过个地方,这地方我觉得各位应该都去过,叫银行,银行各位去银行应该办理过业务,银行是不是有它的窗口,这窗口好比说就是咱们的多个线程,比如说我这银行一共有三个窗口,那我这银行里边三个窗口都打开,三个窗口对外是不是提供我的服务,而我三个窗口同时能处理是不是三个人业务,当我来了第四个人,第四个人处于是不是一个等待的状态,所以这个特点就叫一池N线程。然后各位看一下,我的课件中就是这个。创建一个E池N线程,然后这里写到线程池里边线程出一个定量的,就一个固定的一个值,而这线程可以被重复使用,就是银行那个窗口,当这窗口人办完业务,下一个人到里边是不是继续办业务,他可以重复使用,而我超过一定量的线程,那需要在队列中进行等待,比如现在我三个窗口人都在办理业务,我在来了第四个人,第四个人处于是不是一个等待状态,所以这就叫一直N线程的特点,咱们一会儿会做个演示。
02:24
然后里边还有第二个叫做new上,就是new,这么叫signal threat it,这什么意思呢?它叫做一池一线城。什么意思呢?举个例子啊,比如说我现在这个银行比较小,我的银行只有一个窗口,那一个窗口是不是最多只能处理一个人业务,然后现在我再来第二个人,第二个人是处于一个等待的状态,这个叫一池一线城,是咱们的第二个特点。然后里面还有第三个。你看这个方法啊,叫new catch的slide po catch的什么意思,或者这catch什么意思,是不是有缓存意思,所以这个我强调什么意思啊,这个方法意思就是线程池,并没有说固定的值,根据需求来创建,它是一个可扩容的线程池,比如这句话叫做遇强则强。
03:18
那什么例子,举个例子啊,比如说我现在我的银行一共有十个窗口,但是我十个窗口在我今天可能只开放其中的三个窗口,其他窗口可能没有开放,因为那些人可能今天正好休息,那这个时候呢,比如我的银行突然来了很多的人,那我三个窗口没法处理完这么多人的业务,那这时候银行要做个处理,什么处理?比如银行这个大堂经理,他给另外窗口的人打电话,说您马上过来加一下班,这里边来了很多人,那这些人是不是过来啊,把其他窗口说给他开放,开放之后同时能处理更多的业务。
04:01
而这个时候呢,比如说这个高峰期结束了,那我这里边银行就不需要把所有窗口都打开,它还恢复到最初始的三个窗口,其他窗口是不是继续关闭啊,然后那些人继续回家进行休息,所以这就叫可扩容的这个进程池,遇强则强,根据需求不断变化你的这个线程这个数量,然后最终能充分处理我各个的这个任务或者各个的请求,这是我们线程池的三种最基本分类,总结一下啊,第一个叫一尺N线程,第二个叫一尺一线程,第三个叫一尺可扩容的线程。所以咱们现在把这个最基本的分类给各位做了一个说明,然后说完之后,下面呢,咱们把这三个分类用Java代码咱们来做个演示,让大家感受一下里面这个编写的过程。下面我们来做一下啊。
05:02
首先我在这个里边,我先建个包,咱们来创建,然后这个包我给它起个名字,就叫这个po,就是线程池,在po里边呢,咱们来创建这么一个类,这个类我起个名字啊,比如就叫这个thread。好。一。我们来这么一个创建。然后这个创建之后,我在里边咱们加上这么一个问方法,在问方法中来演示线程池的这个三种常见的这个分类。那我们来写一下啊,首先我写main方法,比如说第一个呢,我先创建一个线程,就是一池N线程。那这个N线程的,比如说咱就建这么一个五个线程的啊,五个线程。就好比说我现在呢,这个银行网点中有五个窗口都开放了,然后咱能同时处理五个人的业务,如果说多于五个人,那这些人要出一个等待的状态,这个叫一池N线程,那咱们来创建,咱看怎么做啊,首先在里边我们用过工具类,叫这个executor。
06:22
Ex写下啊,ECU。Ecs里边这个方法叫做new big thread po里边加上你现成的数量。比如说咱们来一个五。最终大家看它的返回值是什么。各位注意看啊,反义词是不是叫excuor service,然后这里边是咱们创建的第一个建成池,比如说我给它改个名字啊,叫threat这个po。这样的话,咱们现在把这个就创建了,好比说一个银行目前有五个窗口开放了,然后这个创建之后,下面呢,咱们做个操作,比如现在啊,假如我现在银行这里边有五个窗口。
07:08
我加个注释啊,五个窗口,然后五个窗口,比如现在我这里边的正好来了十个顾口,咱们现在就模拟一下五个窗口处理十个顾客请求,里边的过程是怎么样的,那咱们用代码我们来做个实现。首先啊,我在边写个负循环,负循环中咱们就循环,比如循环多次啊,咱就循环十次,然后循环十次过程中在里边咱就来执行这个操作,其实从线程池中是不是要取那个线程这种进行操作,那我们来做一个执行,怎么执行呢?在threat po这个见证池里边有个方法,这个方法叫做exic。挨个CQ里边呢,大家看这个方法的特点。里边是个什么,是不是一个run na接口啊,所以咱就可以直接简化用拉姆的表达式,是不是可以做到是咱们之前说过的,那我现在加上一个拉姆的表达式,然后加上之后我这里边把当前这个线程名称给它输出,因为大家注意啊,这个线程咱们是不是从线程池中给它取出来的,所以我现在就把线程池中这个线程名称给它做输出,后面我加个提示,比如说这个线程正在办理这个。
08:34
业务。现在这个就完成了,然后完成之后呢,大家注意线程池里边的线程,我用完之后是不是还要再放回到将池中,供别的请求进行使用,所以咱要给它放回去,放回去的话呢,在显行池里边有个方法叫做刹down啊,就给它放回去,或者说咱就关闭,而这个过程呢,咱为了效果更加准确,把这个shut down的方法是不是可以放到我们那个final的里边呀,就让它做的更明确,所以现在啊,咱们把结构给它改一下。
09:10
我加上这么一个try catch的这么一个结构。来搞。这里我给他完整一下啊,TRY开我就直接捕获它的exception,然后下面的再加上一个叫finally,然后咱们把这个代码直接拿到咱们这个里面来,Cat里边我直接把它异常做个打印,然后find里边咱就做这个。关闭的操作,或者说把线程放到线程池的这个操作,所以现在这一段基本代码我们就完成了,咱们就模拟个效果,银行的五个窗口去处理十个顾客的请求,那咱们现在把它执行一下,咱们看它有什么效果啊,现在我来执行。
10:00
各位看这个最终的阵行特点。然后大家看啊,目前已经输出了,然后你看输出过程中啊,这里边就是这是它那个线程池中默认那个线程的名称,比如叫这个PO1TH2什么三什么一什么四什么五,所以大家看啊,目前咱们用五个线程是不是能去处理十个请求啊,就是它同时能处理五个,你再来第六个要等待,但是等待过程中可能有的请求已经完成了,所以他继续进行处理,所以咱目前就通过这里边的五个窗口处理了十个请求。啊,大家想银行例子应该能想到银行,比如说就五个窗口,五个窗口是不是能今天办理很多业务,可能办理十几个,几十个,甚至上百个都可以,你其他人只要你多等一会儿应该都能办理到,所以现在啊,这个第一个分类完成了一池N线程。
11:00
然后这个做完之后,下面呢,我们在创建第二个这个电程池,叫做一池一线程。然后怎么做,跟刚才方式类似,咱们用这个exs。里边这个方法叫做new signal threat,然后这里边返回这个对象还是e service,比如这个名字我们叫th po这个二,这表示一池一线程,就好比说我现在这个银行呢,它只有一个窗口。那咱们来把它做个测试。那大家考虑这么一个问题啊,你说线程池中只有一个线程,一个线程能去处理十个请求吗?可不可以?答案是肯定的,是不是肯定可以的,只是说我这里边一个窗口嘛,处理十个请求,那有可能要多等一会儿,但是它绝对是可以处理的,所以现在啊,这个一尺一线程我们就创建了,创建之后咱把这个执行下,我们看一下它的效果怎么样。
12:09
然后大家看。线程是不是都是一有一的线程,是不是能办理十个人的这个业务,所以现在这第二个我们就完成了,然后完成之后呢,下面咱来创建第三个就是一池可扩容线程,因为它根据这个线程数量给你做一个扩容处理,好比说我刚才举的例子,当银行突然来了很多人办理,那银行是不是要临时开启新的窗口,再去办理你的新的业务,所以现在我们来做个创建。就是一尺。可扩容的建成,我们用这个eecs里边这个方法。叫new k式的这个threat point最终返回的这个,咱起个名字叫th po这个三。然后下面我们来用它处理咱们的十个请求,因为这个线程池里边并没有直接固定有几个值,它根据需求自己来决定要创建几个线程,那咱们试一下这个效果。
13:15
大家看啊,这里边12345最大是不是到了五,它一共就出来了五个线程,最终处理我们的时刻请求啊,比如说这个值我换的稍微大一点,再来一个20,现在我再做一个执行,然后咱们看什么效果。你看啊,它最大是到了13个,就是它创建出来了13个线程,最终处理咱们的20个请求,这就叫可扩容的这个线程池。所以现在啊,这里边我们就把这个过程给大家做了演示,这就是线程池最基本的使用方式,咱们演示的三种线程,一池N线程,一池一线程,包括这个一池可扩容线程可扩容特别数明啊,这个线程不是固定的,根据需求决定我要创建多少,当然这个线程,比如说我现在创建了13个线程,处理20个请求,当然比如说我下一次呢,可能我只有这个,比如说只有十个这个请求,那十个请求就不需要13个线程吧,它会根据需求再决定创建几个线程,处理你当前这个请求。
14:29
所以现在咱就把这个渐成池最基本的使用方式给各位就说完了,里边就是这个特点,然后这个说完之后,咱们继续往下看,然后下面看什么呢?比如说大家看啊。我把这个注释先给它都打开。这是我们刚才的三个线程,那比如说咱先看第一个线程,我们到它的源码中看一下,大家看这里边new的是个对象,叫po,是不是is,然后咱再看第二个这个对象。
15:02
你看这里边new的是不是也是threat,包括咱看第三个这个可扩容的new的是不是还是这个对象,所以通过它大家看到了我们创建线程池,它的底层都是去new那个对象叫threat po it。然后通过它来实现咱们线程池的创建。这个也就是它这个底层的原理,它们的底层都是用到了SP po in qor,最终完成了线程池的这个创建,所以各位把这个给它知道,然后在这个th po e qor里边的就是这个方法中的,一共它是有这么就是七个参数,1234567,所以咱们一会儿给各位同学具体介绍这七个参数到底是什么。现在各位先知道三种分类的线程池怎么创建,以及线程池的底层用到了,来po recco,一会咱来介绍这个线程池这个对象中的七个参数到底是什么含义,所以现在把这个我们就做了一个说明。
我来说两句