00:00
好,咱们接着来说呃,继程的方式,创建多线程,这是咱们讲的第一种方式,讲的第一种创建多线程的方式,这呢体现了有这样的四个步骤啊,大家呢,需要去熟悉一下,通过这个写代码呢,大家去记一下这样一个过程啊,那么在这里边呢,咱们需要再多说一下啊,多说几句,多说几句呢,咱们在这块来看,前面这块呢,没啥可说的啊,就是我们继成1S类以后要求呢,去重启这个软方法,哎,我们就重启了,重启以后的话呢,我们首先呢,是创建了一个子类的对象,通过这个子类对象呢,去调这个star方法,当我们去调这个star的方法的时候,诶,接下来咱们发现呢,这个star方法呢,自动的就去调这个run方法了,诶是这样一个情况啊,那么这个大的方法,这个作用是什么?咱们来看一下这个API。在这A篇里边,咱们下边呢,去找这个软方法。呃,找这个star方法在这呢,大方法这个作用我们看一下,首先说使得我们这个线程呢,Begin啊,开始执行,那这个线程就是咱们new的这个对象对应的这个线程啊,因为咱们是继承以thread类了,当然了你也叫,呃,你是thread类的子类,其实也是一个thread,就跟说呢,你拿一个学生继承1PERSON,那你这个学生其实也是个person对吧?哎,就是多态的一个形式嘛,然后我们这块呢,就是使得我们当前这个线程呢,叫开始执行,开始执行这有一个分号。
01:23
分号呢,就意思呢,诶后边还是一个意思,就是它有两个作用,后边这个呢,是说Java虚拟机呢,去调用咱们当前线程的run方法,哎写的非常清楚,咱把这个事儿呢写到这儿,这个大的方法呢,有两个作用啊,一个分号把它分成两部分了,其中的一个作用呢,哟,跑这来了。其中一个作用,写个一啊,那就叫启动当前线程。刚才咱们看这个API这边写的嘛,第二个呢,相当于是调用当前线程的,哎,软方法没问题吧。
02:01
诶,第一个呢,叫启动单元线程,言外之意呢,就是在我们调用这个start就调它之前,包括调它本身啊,这个时候呢,是不是都是我们主线程这个may线程帮我们做的事啊,诶对的,然后呢,我们启动好这个线程以后,接下来呢,它自动的这个start的方法呢,会去调我们当前线程的RA,当前线程按说呢,就是thad这个类当中的run方法了,当然又由于咱们是不是做了一个重写啊,咱们前面讲面向对象的时候说,呃,你要是重写以后,咱们再调你负类中那个方法,是不是自动的就开始调这个子类覆盖负类的这个重写的方法了,诶所以说呢,它会自动的执行咱们这个run方法,哎,就这样一个过程,那run方法当中就是咱们创建这个线程,你想做什么事,你想让这个线程干什么,然后我把这个逻辑呢,就写在这个run方法当中,哎,就这样的一个过程啊行,然后下边这个事儿呢,我们又写了个for,这个时候呢,我们要注意一下,这个for呢,仍然是在咱们的主线程,也就是这个may线程当中执行的。
03:02
啊呃,这个如下的这个操作仍然仍然是在我们这个may方法,把这个may方法咱们称作叫may对应的这叫主线程啊,May线程中。来执行的,嗯,就是这样一个成这样一个情况啊好,那这个呢,我们就说完它了,说完它以后我们再说两个小的问题,呃,第一个小的问题,我们通过start的方法呢,是启动这个线程呢,比上这个线程执行上方法了,那问我们想启动一个新的线程,能不能说不调start了,哎,我呢直接去通过这个T1呢,我去调一个run。我调转能不能是还体现了说造了一个新的线程,然后让他去执行上面这个逻辑啊。能行吗?啊,这个你就用这个逆向思维也能想出来,是不是肯定不行啊,要能行是不是你这个API在这就可以,呃,上面就可以写说啊,我调这个start方法来一个or啊调RA是吧?啊,你要能调run都可以了,那我懒得调start了,他不是明确说了让咱们调的是start方法对吧?哎,说明呢,咱们调这个run是不行的啊,那我现在写的是run,我要执行,嗯,会报错吗?
04:25
对报错就不会了啊,那我正常执行的话连出来,只不过这个时候呢,大家不管你执行几遍你都会发现呢,诶都是先执行的上边这一套是吧,然后接下来呢,98完了以后,接下来呢,才执行的这一套,这个知道为什么,嗯,因为你现在就没有多分出来一个线程。就只是一个造了对象调方法,这个方法执行完以后,是不是才会走下边的逻辑了,诶,那也就意味着我们这个调的run方法,这个run方法里边的这些逻辑仍然是在咱们这个主线上当中做的,哎,仍然是在主线上当中做的,这个事儿呢,我还可以通过另外一个方式呢,去证明一下,哎,我这样来写一下啊,咱们,呃后边呢,会讲这个线程常用方法,咱们这块先用一下,我在这个位置呢,我可以有一个叫什么呢?叫thread这个类,还有一个呢叫current thread,就是当前这个线程,我呢调一下它呢,叫get name,就是获取咱们当前线程的名字啊,然后我这块呢,加上一个,哎,冒号吧。
05:34
哎,加上一个A,然后呢,同样呢,我们把这个事呢,我这样子啊,CTRLCL一下。对,我们放到这块这么着好,那现在呢,我写的是run,写的是run,然后大家看一下我执行啊,下边呢,这块你看我们这个当前线程名,它是不是叫may啊。那就相当于我们这个主线程呢,它自动给起了个名叫may啊,然后呢,你会发现我们上边写的这个重写的转化当中,这个还是美。
06:05
那既然还是made跟下边一样,说明呢,我们这用的是同一个线程,那都是这个主线程,所以说这块呢,只是体现了一个对象调方法,根本就没有开启一个新的线程啊,或者你从这块来看,咱们start有两个作用,你现在呢,只是试图呢去调的这个RA,根本这个线程呢,就没有启动起来啊,所以说这是咱们说的第一个问题啊,那如果我们换成这个start的时候,哎,你看我这时候保存一下,我再来执行。诶,你看这呢叫may,然后往上走,大家看啊,你看这时候这不是出现这个交互了啊,我们这呢叫TH杠零,这相当于是给我们默认起了个名,哎,就是哎我新起了个县城,它起名叫四二杠零,我要再起个呢,哎,你可能要想可能就要杠一了是吧?哎,是这样子的啊,相当于它默认有个名,这个呢,你就明显的能够看出来,我们这是两个线程了。所以说呢,我们要想启动一个新线程,用的呢是star方法,而不能呢直接去调RA,这是咱们说的这个叫问题一,问题一说我们不能通过直接呃使用这个对象点啊,或者叫直接调用啊。
07:21
哎,直接调用咱们这个run方法的这个方式,哎这个启动线程,哎这个呢是注意这是一个错误的,那要想启动一个线程,必须呢,我们调start方法,Run方法呢,也是它顺便呢,就把这个run呢就执行起来了,那这是第一个问题啊嗯,第二个问题呢,比如说我现在呢,在咱们这个程序当中,我再想造一个线程,我再想造个线程,然后呢,也让他呢,再去执行一下这个,呃100以内的偶数。再想启动一个线程。在这我们写一下啊,这个地方问题二说,嗯,这个再启动一个线程,嗯,然后呢,来便利,呃,100以内的这个偶数。
08:13
那这时候大家想,呃,肯定还是要用一下上面那个转了啊,你说我直接接着再拿一下这个所谓的叫T一再去让他START1下行不行,就是你这块呢,这不是跑起来了,执行上面吧,然后相当于起了一个,哎,我这块呢,再让你跑一下,感觉上好像不太靠谱是吧,我们执行一下试试。你看你看这块报错了,前面这块呢,执行了一部分代码,这块呢出来一个叫illegal thread state exception说叫非法的线程状态,嗯,然后这块呢,这个start呢,我们点开看一下啊,点开看一下话呢,这是叫thad一个status,说如果你这个status不等于零的话呢,就会抛这样的异常,这不是咱们刚才抛的这个异常嘛,诶那通过这儿呢,你大概也能看出来,就是咱们一个线程呢,你首次掉的时候呢,它的这个status状态相当于就是个零,哎,所以说呢,它就执行下边这个逻辑了,哎,然后当你呃再去调这个star的时候呢,它这时候状态已经不是零了,那不是零呢,它就抛异常。
09:19
那么,言外之意。言外之意就是我们这个star的方法,对于一个线程来讲,是不是只能让他去start的一次啊,诶,对的啊,就是你不可能或者要不可以啊,通过让这个线程再去start这个的方式,再去起一个新的线程并执行了啊这个咱们这说一下啊,这是一个呃,问题二啊,再启动的线程便利100以内偶数我们说还不可以啊,还让已经哎start的这个线程。哎,去执行啊,然后这个时候呢,我们会报这样的一个异常,哎,就是它。啊,不能这样去写,那既然不能这样写了,那应该怎么办呢?那你就别用这个题了,你是不是再new一个呀,对的啊,这个时候呢,我们就需要啊,再去新建一个,我叫T2啊,这时候你拿这个T2。
10:17
哎,我去让他呢,做一个start。哎,这样是OK的啊,然后我们执行看一下。诶,你看这个时候,嗯,往上一下啊,嗯,这个时候呢,你看我们有这个叫THREAD0,这就相当于是这个T1,然后thread杠一呢,这就当于是我们又新建了一个T2,哎然后还有我们这个may主线程,哎他们交互的这样的去执行,哎这样的是OK的啊也就是说呢,我们需要呢,哎需要啊重新哎创建一个哎创建一个哎线程的这个哎对象哎然后呢,让他呢去start啊行,这呢就是我们说的这两个问题,诶通过这两个问题呢,大家再去熟悉一下咱们说到的这第三步和第四步啊,要想创建多个线程,你就去造多个对象,然后呢,要想启动这个线程,只能去调star的方法。
11:13
不要直接去掉那个run啊,OK。
我来说两句