00:00
好,那么我们这一章呢,还差最后一个内容,呃,这个内容的话呢,叫呃,JDK5.0新增的线程的创建方式,呃,其实呢,从这个这个知识的这个完整性上来讲的话呢,其实我们该涉及到几个内容呢,都涉及到了,只是说呢,我们在这个JDK5.0的时候呢,新增了两个线程的创建方式,对于我们原有的继承thread类实现random接口之外的一个补充。啊,一个补充了,咱们在这个开发当中啊,真实这个企业级开发当中,实际上呢,我们经常使用的是呃,这里边儿的这个线程池的方式,所以呢,我们也把这个新的创建方式呢,也来给大家一块呢,说一下新增的方式呢,有两个。新的方式有两个啊,第一个叫实现column接口,也就是让大家真正如何去面试的时候啊,这个呢也是一个非常常见的面试题,说呢创建多线程到底有几种方式呢?这个时候呢,你就不能光说有两种了啊,这就太老了啊哎,那你得说有四种,诶第三种呢,就是叫实现call接口啊,另外呢,还有一种呢,叫使用线程池,诶我们把这个呢也规程啊,叫创建多线程的一种方式了,那咱们就先来说一下这个新增的这个,呃,这个方式一啊叫实现column接口,下边呢有个说明,说呢与实现randomable相比呢,这个column接口这个功能呢就更强大了,怎么叫更强大的呢?我们在这个reno接口当中需要去重写的,这叫run方法,而我们这个Co切口当中呢,我们需要重启的是叫什么方法呀,猜一下。
01:38
哎,Reable,重写run column呢,重写com,对,你想一下就行啊,你像咱们以前说过那个什么c c above,那里边呢,就是个C方法是吧?啊就是可什么什么的里边呢,它基本上就会前面这个就是它的一个抽样方法,这个呢,我们需要去重启,这个叫靠方法,这个靠方法呢,比我们这个run方法呢,哎,特别之处呢,就是这个靠方法可以有返回值,诶那就成了我们这个分线程做一个事,做完以后呢,它还可以返回一个结果。
02:09
给另外一个线程用,哎这样的话呢,不就这个功能更强大了是吧?哎,另外的话,我们这个方法呢,还可以抛异常,哎你抛的异常呢,还可以对外边呢去接收,接收以后呢,我就知道一个线程出什么问题了,诶这个run呢是不行的,Run里边要有一场,只能是拆开,你里边处理完了以后,外边我想看看不到是吧,而我们这个call的话呢,这个回调方法啊,这个靠方法我们可以抛异常,其他的线程呢,把这个异常还可以拿到是吧?诶你就知道它里边出什么问题了,哎挺好的,另外呢,它还可以支持泛型,这个泛型的话呢,我们放到。放到这块说,哎,这儿说这个泛型,咱们现在讲的时候呢,可以先忽略掉它,当然呢,也可以给大家演示一下啊,另外呢,这个Co要想使用呢,还需要借助一个叫first task这样的一个类啊,那不多说了,咱们直接在写代码来演示一下,在咱们这个JAVA2的包下呢,去新建一个呃,Java的class,嗯,这个呢,咱们就叫一个词red new。
03:07
哎,创建的线程的新的方式,哎创建诶线程的这个叫方式三啊,我们叫实现column,哎这个接口的这个方式啊,那这个呢,是咱们在这写一下啊,JDK这个5.0新增的。所以说呢,咱们在看这个API的时候啊,咱们当时讲这个前两种方式的时候呢,是参照这个API了,API里边呢,说说there are to啊,Methods啊两种方式或叫to with啊去实现这个这个创建多线程,那个API呢比较老啊,说呢咱用的也不老啊,是咱们用的是8.0,但是8.0里边呢,写8.0那个人呢比较懒是吧,没有把那个API的那个说明及时更新啊,那里边还写的两种,实际上呢,在5.0的时候呢,又增加了新的这个方式了,嗯,那这呢就提到了实现reable接口啊,Colorable接口的方式,好,那么咱们去写一下啊,这呢我写一个class,嗯,比如说我就叫个number的一个thread了,嗯,让他呢去implements叫column,嗯,这个时候呢,你发现column后边那个监控号,这就是所谓的泛型,目前呢,大家还不知道啊,那暂时咱们就先这样来写啊,Coll,那接下来你就需要去这个。
04:29
实现人家这里边的抽样方法了,Al enter一下啊一回车,这里边有个方法呢,就叫做call啊,这个call就是相当于啊,相当于咱们的这个RA方法一样,嗯,这个呢,我们靠方法在我们这个接口当中呢,它是可以throw一个exception的啊,那我们既然你这个嗯接口当中呢,是可以抛异常了,那咱们这个呢,自然也可以去抛异常啊,这是比较好的一个点,那么咱们这个靠方法做一个事吧。那咱们就可以做一下变利100以内的偶数也行,便利100以内偶数,并且呢,返回所有偶数的和,哎,我们这呢有反回值,行,咱们做个这个事儿,For,哎,直接for a一下,哎,这个我们让它从一开始哎,然后呢到哎,小于等于吧,哎,100,哎,我们说如果I取模二等等于零。
05:27
哎,那我们这呢就诶让他呢输出一下啊i.s out一下,哎,或者呢,你这要不想输出呢,就不要这个了,我们关键呢是想要一个总和一个sum,一开始是零,在这里边sum诶诶加等于这个I。这个I呢,是这个输入法的一个换肤的一个换皮肤的一个操作了,挺恶心的。这样,嗯,好,那这呢是我们一个for循环,那结束以后呢,我们在这去return一下sum。
06:08
诶,我就呢,返回了,返回这个sum这块呢,其实又涉及到一个转换啊,咱们这写了个int类型,Int类型是我们object的子类吗?不是吧,对,Object是这个类层面的,Int是基本数据类型啊,没有这个集成关系,这呢相当于我们把这个int呢,是不是又转换成了。诶,包装,呃这个装箱了一下啊,然后enter Internet作为object这个词类,诶相当于是赋给了一个object类型,相当于一个多态的形式啊行这呢大家都能理解,然后呢,我们这就算写完了,回到这儿,回到这的话呢,讲一个main方法啊,首先呢,想到的就是我们去造一个它的对象呗,CTRLC,诶CTRLV,这呢我就写一个叫嗯就叫他吧,诶new一个诶number thread,好这呢我们就造好了,那造好以后,这时候呢,你想通过它呢,调呃,调这个呃,Thread,调startad,它也没有啊。
07:05
啊,你这时候呢,实现了我们这个,诶,实现了我们这个这个Co这样一个接口,他也没有这个所谓的thread作为它的类了,所以这是不行的,那么要想使用呢,我们还需要去借助另外的一个类啊,叫做further task。这个F呢,其实又涉及到另外一个接口,叫做first接口。啊,说这个further接口呢,可以对具体的reable或者是collable的任务执行结果啊,进行这个取消啊,查询啊,是否完成啊,诶获取结果啊等等这样的操作,那么这个further接口呢,有一个唯一的实现类就是further task啊可以实现,呃,这个further task呢,同时还实现了这两个接口啊这个了解一下就行,那么这里边我们怎么做呢?我们去需要new一个啊叫further task。哎,去new一个这个F,这个泛型呢,暂时先不考虑这个f task,哎,我们这块呢叫嗯,Ctrl out斜杠,哎我们这个调出来它这个构造器,其中有一个构造器呢,需要传一个Co的实现类的对象,就是我们这里边的哎,Number thread。
08:13
哎,这样呢,就放进来就行,哎放进来以后我们在这个位置呢,哎给它呢,Al enter。哎,这个呢,让我们去try to,它这个这个执行下边这个,诶,生成一个变量,哎,我们就叫做further task,得到一个further task的一个对象,那么这个further task啊,你这块广式生成个对象呢,我们可以调它的一个什么操作呢?这个一个叫get的方法,就返回了一个值,哎,这个get的方法呢,它还抛一个异常,你看是吧?哎,那我们给它拆开一下啊,那么这个get呢,我们out enter一下。哎,让他呢,接收为一个值,这个值呢,其实就是咱们上面得到的那个sum。咱们some点一下。
09:01
哎,我通过这个first调这个get的方法,就可以获取我们行三这个column接口,实现类对象的回调,这个其实叫回调方法啊,就是咱们没有显示的去调它,哎,我们去调的是呃下边这个结构,然后呢,它自动调的这个方法啊,习惯上叫一个回调方法了啊调到这个方法,然后呢,返回值就是我们这个get的返回值在这儿呢,我们说明一下啊,说这个get方法它的返回值。即为啊这个further task。哎,构造器。行参,哎,这个别叫行参,叫参数吧,你这相当于是食参了啊,参数column。嗯,这个我就直接叫call对象了啊call对象嗯,这个啊,或者call叫实现类吧,啊重写的啊,这个靠方法的,它的返回值相当于呢,咱们就把这个100以内的这个偶数啊这个和哎,就通过这个钙的方法呢,就给返回了。
10:12
哎,就是这样的啊,那么这样的话呢,直行就OK吗?我们跑一下看看。你会发现诶没有任何结果,而且呢,你看还结束不了。这样啊,这个时候呢,我们说还是不行的啊,洋外这呢,就是我们当前这个线程,其实你还没有真正的让它启动起来,它还调不了这个靠方法,那要想让它启动起来呢,咱们诶还得是怎么着呢,去new一个哎red。哎,咱们前边讲说创建线程的两种方式,哎,那其实我们相当于啊,都是用了两个thread,只不过第一个呢,是你thread一个词类了,其实也是一个thread,哎第二个呢,我们也是new了个thread啊,咱们呢是这个把那个诶reable的那个这个参数放进去了啊总归呢,就是咱们都得是new个thread,主要目的呢,是因为我们要调大的方法。
11:04
啊,主要是这个原因,那么你用一个thread,我们ctrl out斜杠一下看一下这些参数啊,参数咱们用的谁呢?实际上还是这个叫reable啊这个咱们就把这个further呢放进去发现呢没有报错,因为呢,咱们这个further task这个类呢,它也实现了randomable接口了。嗯,你这样你点一下也能看得到,嗯,它呢,First实现了,实现了它你直接看它,它实现了random。哎,所以相当于咱们这个first text,它实现了random接口,我就可以放进来了,诶这样的话呢,我们就把这个线程呢给启动起来了,启动完线程以后,实际上呢,这时候呢,就开始去执行了,就。啊,就执行了,如果说大家对这个,呃,靠方法的返回值不感兴趣,你就不用再去调下边这个概念了。哎,如果你要是感兴趣,那你再去调这个get get的目的呢,只是为了获取我们靠方法的返回值啊,就这样子来我们执行一下。
12:10
哎,这呢,大家往往前走,嗯,返回值这块我就别这样写了,这样写你就看不出来了,我们这儿加一个话说叫总和为。嗯。哎,这么着,哎再跑一下。那这呢,我们就能看到这个数了,总和为2550。哎,这样个情况,诶上面呢是咱们这个分线程打印的这些数据,下面这个呢,是咱们在这个主线当当中把这个和呢给它输出了,诶所以我们稍微总结一下这个步骤啊,哎这呢可以看成是我们的叫第一步,哎说呢叫提供啊,或者叫创建啊,创建一个实现啊,这个call接口的实现类。
13:04
哎,这是第一步,然后第二步呢,需要我们去这个,嗯,要重写或者抽象方法,人家都要实现了啊,那我们需要呢,去实现这个靠方法,诶将这个此线程需要做的这个操作呢,生定在我们这个靠当中。将此线程需要执行的这个操作声明在我们的这个靠方法中,行这呢是咱们的这个第二步啊,同时呢,我们这个靠方法呢,是可以有返回值的。哎,你要是不想要防位值,你这个时候就return no呗,哎那就没有了,好,这呢是我们的第二步,然后第三步呢,这是第三步,哎需要呢去创建。这个。接口实现类的对象。
14:02
然后第四步呢,这个就涉及到另外一个叫further task啊说诶将此呃这个column的实现类对象。哎,它呢,作为参数传递到。哎,咱们这个叫further task这个构造器当中。哎,去创建咱们这个first task的这个对象,哎,然后呢,最后一步,哎其实也谈不上最后一步主要呢,看你感不感兴趣,这个反回值照啊不感兴趣的话呢,这就是最后一步,这呢我们相当于是呃将哎further text它这个类的对象。作为参数传递到咱们thread类的构造器中啊,然后创建thread的对象。哎,然后呢,并哎大的方法调用。
15:02
诶相当于最后这个呢,我们两个给合成一个了啊直接呢,我就在这调start了成,那么如果说呢,大家对这个,呃,我们上面这个靠方法这个返回值感兴趣的话呢,你还可以再多一个操作,这就是咱们所谓的叫第六步。啊,第六步呢,我们可以去获取这个,嗯,我们叫这个column。嗯,How,这个嗯中的靠方法的返回值,哎,这就可以了,如果大家呢,像咱们前面讲的啊,我只是遍利一下100以内的偶数,我呢不需要你返回什么,那你就在这呢,Return now,那就说明你对这个反位值呢不感兴趣,不感兴趣呢,你这个第六步呢,就不要了啊如果呢,有的时候呢,大家,呃,这是一个线程啊,这是另外一个线程,这另外一个线程呢,做完以后呢,它需要呢,给我们这个线程一个东西啊,然后我们这个线程拿到这个东西以后呢,我再接着往下走,那这时候你需要给我一个东西,这个就意味着呢,你必须呢,诶调完这个你线程的这个回调方法以后,就是我们上边以前叫run,现在叫靠方法啊,调完以后呢,你需要给我一个东西,把这个东西呢,给了另外一个线程,你就需要呢,拿这个get的方法去调,哎就成了啊行这呢,就咱们说的这六步,哎大家呢也呃下来呢,可以试着去写一写,那这个说完以后呢,我们关注一个问题,什么问题呢,就是刚才呢提到了说这个。
16:26
呃,实现reable接口和实现Co接口是创建多线程的两种方式啊,这里边呢就提到说它呢更强大一些,那么如何理解这个cable比reable强大啊?哎,如何理解实现Co接口啊的这个方式啊,创建多线程,哎比啊实现runable接口。比实验reno接口呢,创建多线程啊要强大。
17:09
这个其实咱们刚才也提到了,主要呢,大家把这个点是不是就归结到咱们这个靠方法这块啊,哎,这里边就提到第一个,哎,咱们这个靠方法,哎这个靠方法呢,是可以有返回值的。啊,就是你这个分线程执行完以后呢,是可以给另外的线程返回一个结果的啊,这是第一个事儿,然后第二个事儿,我们这个靠方法呢,是可以,哎抛出异常。哎,抛出异常,然后呢,诶你这块抛出异常了,咱们回头呢,是不是调的时候呢,可以在这块补货异常,诶根据你补货的异常,你是不是感兴趣,我们呢,可以诶拿到这个异常的一些信息,像咱们讲这个项目三的时候啊,说抛了一个异常,这个异常呢,说叫找不到指定的指定的这个员工啊又抛了个异常说叫呃这个呃比如说超出了这个最多有一个架构师啊,你这给多了,相当于咱们拿到这个异常呢,你打印这个异常的信息,是不是就知道他到底出了什么问题了,哎,当然我们前面这个乱方法呢,你只能是在里边去拆,开始拿不到它里边到底出了什么问题啊,哎,他呢可以抛出异常被哎外面的操作捕获啊,然后呢,获取这个异常的这个信息,哎,这是第二个,诶第三个的话呢,哎,这也是基于咱们说的这个有返回值的这个事儿啊,这个Co呢,它其实是支持泛行的。
18:34
哎,他是支持泛型的,只不过呢,咱们目前呢,还没有讲,哎,目前还没有讲啊,嗯,大家其实要是见一下的话呢,就相当于我们在这个Co这块啊,让你看一下啊看一下,然后我就删掉了。啊还没有讲啊,在这个call后边呢,它声明的时候呢,有一对监控号,我们就可以在监控号这里边呢填一个类型,比如说针对于咱们这个问题呢,咱们返回的呢是一个总和,总和呢是一个整形,所以监括号这块呢,我就写上叫TE对TE,那这上一写上TE以后呢,这个位置呢,类型就依据它来决定的,所以我们CTRLC把这个呢就替换一下。
19:16
哎,这那就是integer了,好认认识integer以后呢,再往下走,咱们这个,呃,Get这块呢,我们看一下它哈,哎放到这这个时候呢,你看我能不能把这改成一个叫integer。哎,他这呢,你看说不行,说呢,哎,你找到是个object,你试图呢,改成还得强转,那说明呢,我们这时候呢,还认为它是一个object啊为什么呢,因为这个位置呢,我们这个further task它也有一个,它也是一个泛型。哎,他这也有个反型,所以呢,哎这块一说呢,就得再复杂一点,我们需要在这个位置啊,你也指明哎是一个阴体这哎,然后这个位置呢,哎也得需要这样加一下啊才可以,这个里边呢,你写上也行啊,哎后边其实有心得性就可以省略了,严格上来讲呢,这块都得写上,写上以后。
20:10
哎,这时候呢,你看我们get,它就认为你返回的就是一个了。这就是属于泛型的一个作用啊,就非常明确的,我们得到的是一个什么类型啊,由于咱们泛型还没有讲,所以大家呢,就暂时可以先忽略啊,我就撤销了。哎,我就都撤销了,还回到咱们最初的这个情况,哎就都不要了,哎就先这样啊,这呢就是咱们说的这个,诶colorable呢,相较于咱们这个renoable呢,它的一些还算是优点啊,这个大家关注一下这种创建方式。
我来说两句