00:00
然后接下来我们从这个代码层面上来看一看如何呢去实现多个线程的创建。那就是涉及到了叫创建和启动线程。首先的话呢,我们说这个扎瓦逊尼的话呢,它是支持多线程的。所以呢,我们才可以呢,去创建多个线程,那线程呢,这块涉及到了有一个类,哎,Java点浪下的一个类叫做thread,那么这个类呢,就代表的线程,那如果我们创建一个线程,实际上呢,就可以理解成创建这个类的一个对象。对一个对象呢,它就对应的是一个线程。好,那我们该如何去创建呢?那很自然的我们就会考虑说关于这个类该如何去使用,那我们就来看一看这个API,这呢我们就直接搜索一下,叫做thread。这个单词最起码得会念。而且是特别常用的一个单词,你也不能念的太过分啊,Three不行。别念错了啊。更不行是吧。好,来看看他啊,现在首先呢,一个thread呢,它是一个线程,是一个程序执行过程当中的一个线程,说Java虚拟机允许应用程序由。
01:05
多个县城。啊,并发的去执行。哎,说白了就是我们扎虚机呢,是支持多线程的。好,下边啊,说每一个县制呢,都有一个优先级,哎,怎么怎么样的,这个咱们就先不说这个事儿了,这是讲线程优先级的问题的,咱们先再往下看,看到这儿啊。是there are two ways to create anew threat of execution,什么意思啊?有对两种方式呢,用来创建一个执行当中的线程。说one is to啊,第一种方式说the other way to,这呢,就是两种方式吧。那这块呢,我们就开始来看第一种方式啊,说第一种方式呢,是声明一个类,让它作为我们thread类的一个子类。这第一步啊第二步,所以这个此类的话呢,需要去重写一下。这个类的run方法。
02:00
啊,这呢,可以理解成是我们的第二步方法的重写,然后接下来啊,说an instance of this of the class,说你当前这个子类的有一个实例。就可以呢,接下来被分配和执行了,这块说的稍微有点快了。啊,那你要是看不太清楚呢,下边给你举例了啊,说我们举个例子,说我们现在呢,去创建一个线程,用于去计算呢,比指定的这个数大的这个质数呢,都有哪些可以这样写。第一步呢,创建一个类,去继承我们的thread。第二步的话呢,去重写方法。哎,他前面这块呢,说比指定的这个数大的啊,是哪个数啊,它这块定义了一个属性。啊,然后呢,给大家做一个赋值,OK好,接下来我们就创建当前啊这个thread这个类的一个对象了。此类的对象,然后呢,去调了一个叫大的方法。说the other ways to啊,就相当于这就完事了。那么当我们去调大的方法的时候呢,它实际上呢,就会去调我们这个run方法。这个run方法里边就是我们当前这个线程,你到底要做什么事,把要做的事写到这个re里边就可以了。
03:07
啊,相对来说说的比较清晰,那么回过来咱们记录一下看一看啊,首先第一种方式,我们就把它称为呢,叫继承thread类的方式。啊,因为我们第二种方式呢,就不是这样子了啊,第一种叫其中四衰类好,那么具体的步骤呢,回忆一下我们刚才说的啊,首先第一步。创建。啊,一个记成语。哎,类的这个子类是吧,好,那么第二步呢。重写。对,Thread。软方法。那么这个方法呢,我们要重启了,主要呢,其实就是写这个方法体了哈,那这个方法体怎么写呢。或者叫写什么呢?对,那么这个run方法的这个方法体啊,就是咱们当前你创建的这个线程,你想让它做什么样的操作是吧,也就是说呢,将此线程要执行的操作声明在此方法体中。
04:10
诶,注意啊好,那么第三步呢。对。创建呢,咱们当前的子类的对象。然后呢,这是第三步,然后第四步呢。对,然后呢,就是通过对象。诶调用咱们说那叫start这个方法,那我们当前这个此类的话呢,也没有去重写这个star方法,或者也没有声明过star方法,那么问这个方法是谁的。对,那只能是负类的了,你负类你thread了,是不是就thread里了。诶没问题,好这呢就我们这四步,OK,那下边我们写个例题啊,说创建一个分线程叫一,然后用于便利100以内的偶数,诶我们来做一下这个事儿,诶CTRL一下。诶,咱们这时候呢,就在这个位置啊,叫thread这个里边我们去执行好,我们右键啊去。
05:05
创建一个这个呢,我们是要打印一个偶数是吧,偶数呢叫做even。的一个测试,哎,我这样来写了啊。好,就粘到这儿了。哎,回忆一下啊,我们刚才说的这样的几个步骤,哎,CTRLC咱们给它粘过来。哎,粘过来的话呢,这个咱们先这样吧,这样注释一下了啊。哎,第一步啊,第一步我们把它粘到这儿。创建一个继承于12类的子类。啊,Class一下这个呢,不妨我们比较print吧。让他是吧,然后呢,去继承于此。哎,这是第一步,第二步。重启转方法。在这啊好,那这个重写的话呢,一方面啊,你可以呢,按住CTRL键呢,进入到thread里边,把这个run呢找到,然后呢,把它的声明粘过来,或者的话呢,也简单一点,直接你就写run就行是吧。
06:00
你看这是不是就可以了。这就我们要重启的这个事儿好,那么我们要做的事儿呢,是便利100以内的偶数啊,这个操作呢,也比较简单直接呢,你就写就行了。啊,这个我就到100是吧,这个呢,从一开始吧,小于等于啊。判断,如果I呢?曲目二相当于零。那我们就打印这个I。哎,这就妥了。比较简单。写完了啊好,然后第三步呢,叫创建当前threat子类的对象,那咱们就在这个测试类里边写个main方法。哎,在这写。这在咱们的第三步,你要看着别扭的话,你不行,你就把这个先写上边这个,咱们这个写下边儿了,就啊创建当前thread类的这个对象了,那我们就创建一个print number的一个对象。啊,线程线程thread,我叫T1吧。再去扭一个。哎,当前我们这个的对象,这第三步好,第四步这个。哎,通过这个T1呢,我们去调这个叫大的方法。
07:03
那就可以了。好,那么四大方法呢,刚才我们也说了哈,当年这个print number这个类呢,我们也没有呢去定义这样一个方法,然后呢,你也没有所谓的这种啊,重启的这个概念啊,那就意味着我们掉的就是负类里边这个方法了,然后我们按住CTRL键的一点,确实呢,就定位到我们这个thread里边了。啊,没问题啊好,然后呢,这个start的方法是什么作用呢?我们可以看一下这个API,往下走找一下,这个叫start。哎,就它啊这呢,就说明了它的一个作用说呢,使得我们当年这个线程呢开始执行。哎,相当于我们把这句话呢,翻译成叫做启动线程。然后分号。就是下边呢,是另外的一个意思说呢,Java虚拟机会去调用当前线程的run方法。诶,非常的清晰,所以回过来关于这个大的方法的作用,我写到这儿有两个作用啊,第一个作用。叫启动线程。
08:00
啊,第二作用。哎,调用。对,当前现成的软方法。好回过来啊,看一下我现在呢,第一个作用启动线程启动起来了,现在就是一个分线程了,然后呢,它会调用当前线程的软方法,那按说的话呢,你看我们API这块啊,当前现成的run方法,按说就是你该上边的这个run了。就掉了是吧。但是这个方法呢,在我们thread里边定义的是不是被我们这个子类给。重写了是吧,那重写是不是就覆盖了。那么调这个是不是就掉自己的这个了。所以说呢,我们下边一定要start,是不是就它就执行了。OK啊,好,这时候我们去做一个run。诶这块我们发现呢,就是100以内的这个偶数呢,我们就打印出来了。哎,就是这样的情况。但是大家呢,似乎说呢,这个跟在main方法里边写也没看到有什么区别呀,也感受不到说这是一个新的线程是吧。哎,那这块怎么办呢。
09:01
啊,咱们可以这样,比如说我在下边儿这块是吧。注意我说呀,下边这块的代码呢,就是咱们的这个没方法执行的这个先生做的这个事,而我们上边这个run方法里边呢,是我们新创建的先生做的事儿。那你比如说看啊,我把这个代码我CTRLC一下,我就在这儿写了一份。哎,这个呢,理解成呢,是咱们没方法所在的线程执行的操作。而这个呢,是我们的这个新的造的这个县城T1做的这个事儿。啊,那里边儿有点不太好区分,咱们稍微的这么着一下吧,比如我在这个后边呢,咱们我整一点这个星吧。这样子的啊好,那这时候咱们再去做一个run。看一下。没有交互是吧。差点意思是吧。其实这块呢,它实际上呢,是有可能会有交互的。
10:02
还没有。这个因为这个数的话呢,也可能咱们整的太小了,他一下子就整完了是吧。1000呢,1万也行。来,我们再去run一下。这个要出不来,是不是会有一点尴尬呢?是不是又交互了?诶,那有交互呢,就体现出来了,就是我们这个线程执行一段,那个线程执行一段,说白了就是我们现在呢,其实两个线程都在执行嘛。所以呢,那你是谁先执行一段后执行一段,这个都有可能发生,所以呢,会出现这样的交互的这种场景,这呢就体现了是两个不同的线程啊,诶还可以怎么做呢?诶我再明确一点的话呢,我在这块加一下这个,呃,一个方法大家会看的更清楚,这儿呢,也是我们讲完多线程创建方式以后呢,我们要讲的这个方法了,我就先提前用一下啊这个RI呢,有个方法呢,叫做。Current thread,然后一个。来个冒号吧。
11:00
诶,这个名这个作用呢,就是获取当前我们这个执行的这个线程,它的一个名字啊,那我同步的把这个呢,CTRLC一下咱们放到这儿啊。那这时候呢,我们再去做一个。啊,这是大家大家看啊,这个时候的话呢,我们这个说may方法,它所在这个线程做的操作,这时候这个线上啊,它默认有个名就叫做may线程。就是我们所说的叫主线程啊,然后呢,你再往上拽。这拽的有点费劲了哈。这个咱们干脆呢,就整100吧。好,这个呢,我们重新再再去run一下。诶,你看这个交互这就有了哈,然后这个呢,你发现呢,我们创建的这个线程呢,叫T1线程,这个T1线程它默认也有个名,你看叫right杠零是吧。就是这个线程它呢是96啊94诶也没问题,这个名怎么来的呢?其实也很好理解啊,你看我们这儿呢,是不是new当前这个类的对象,它其实默认的是不是叫修克空啊。这空就是我们thread里边吧。
12:01
里边呢,大家去找啊,CTRL f12,咱们找这个空三的构造器,就这吧。这个呢,其实它调当前其他的构造器的时候呢,在这个位置就是给县城起名的。这个name就是起名的哈,此二的杠,然后这块呢,会调一个方法,那么这呢,拿这个值呢,加加这个值呢,你看默认就是零,所以你第一个限制呢就是零,第二限呢就是一啊,第三个就是二,以此类推,就是四的杠几。哎,就这个思路啊,也就是说当我们不去起名的时候呢,默认它有一个名啊,就这个意思。好,这呢,就咱们创建的第一种方式。啊,大家呢,去熟悉熟悉啊,那么这里边儿呢,我们需要针对这个代码进行一个分析啊,你看我这样说。这是一行代码,这一行代码,这两行代码你说是在哪个线程里执行的?对,注意呢,是主线程,也就是说诶,我们这个分线程对应的这个对象的创建,包括呢,这个线程的启动,都是在我们这个主线程中做的,只不过呢,在我们这个may方法一进来哈,这呢是一个线程在执行,就是我们这个主线程执行到这个star的时候呢。
13:04
诶,他这块呢,是不是又重新开了一个线程啊。就是我们这个提议这个线程它呢,就执行上面软方法了,而我们这个主线程的话呢,是不是继续还往下执行。所以我们现在来看的话呢,诶,这就相当于这是一个线程,这个线程它俩呢在执行。OK啊,这就是有两个线程。没问题,这个说完之后的话呢,给大家抛两个问题。第一个问题,比如我在这块去洗了啊。我叫问题一说呢,我们此时呢,启动这个线程,包括调用上面run方法呢,用的叫说呢能否使用叫呃t1.run去替换。咱们一这个方法调用。啊,切换它干嘛呢,就是启动一个新的线程,然后呢,调用上面的软方法。啊,能否使用它替换它的调用,然后呢叫实现呃,分线程的。
14:02
创建。和调用。对,有同学呢,会说说你这个star方法目的不就是调转,那我就别调start了,我直接自己主动的去调转不完了吗?试一下。我就这样掉了是吧。那么这个时候呢,我们要执行的话呢,你看下这个结果哈。似乎呢也没什么问题,但是你去细看的话呢。你看到了吧,没交互是一方面,还有。咱们刚才那块看的叫二杠零是吧,现在你看都不叫杠零了。他叫may了,相当于呢,他认为呢,上面这个run方法呢,是主线程做的。能理解吗?哎,对啊,就是相当于这个时候的话呢,我们调run呢,就是主线程当中过来以后呢,调了一个普通的方法方法方法回去呢,去执行这个run,执行完以后再执行这个may。他其实这时候呢,是不是就只有一条执行路径啊。哎,所以说这不叫多线程问题了,就一个线程。
15:03
对,诶,包括你看我这块,我也写了一个代码,就是这个代码的话呢,大家体会一下它是不是多线程。啊,没方法进来。造了一个当前这个类的一个对象,这个对象呢调MA2。S2里边调一。没了。这是单线程还是多线程?注意是单线程,诶你不能理解成说,诶你看我这me也掉了,MA2也掉了,这俩方法都掉了,这不得两条线程吗。这个就大错特错了是吧,所以说这个线上的话呢,大家你就这样看哈,我能不能拿一条线给它穿起来。哎,你看这时候呢,我们造个对象进来调MA2,是不是就调到这了,ME2又调MA1,是不就掉这个了。没了是吧,呃,一条线能够穿起来,这就一条执行路径,那这儿呢,就是一个线程。哎,那跟我们刚才这块。类似是吧,我现在呢,这一条线程过来,我这块穿穿到这儿呢,穿start了,Start的话呢,直接就穿到你上面这个方法了。
16:02
把这个方法执行完以后,我们又去执行下边这个了。所以这就是一个线程。啊,而我们这个不一样。诶大化呢,我们说有俩作用,第一个呢叫启动线程,然后呢调用转方法,你要是光直接调转的话呢,相当于线程没起起来。就还是一个只有主线程啊。这块大家注意一下,这是我们说的第一个问题,哎,能否替代它调用生态调用呢?这个我们说的不能是吧。好,这是一个问题,然后再来一个啊。哎,这个问题二。诶说呢,我们现在呢,启动了一个线程,调一下,打印一下100以内的偶数,我现在呢,假设呢,需要你再创建一个。分线程,然后呢,同样的去便利100以内的偶数。啊,再提供。一个分线程。哎,说用于啊,100以内。偶数的一个便利。
17:00
那么这时候我们该怎么去做呢?对,我们能不能直接呢,再拿着这个T1你再跑一遍。对大家呢,直观感觉说不行是吧,那我们这块呢,你运行一下看看。这块的话呢,你看下边这块没问题,但一开始这块呢,出了个问题,说呢叫illegal,在我们这个第十。出现的,然后他呢,又调了我们这个thread start方法的这一行代码。在这行这块呢,出的一个这样的异常,是不是就报的也是他啊这块呢,提到了一个叫thread的一个status啊。那也就是说,当我们首次调用这个ad,哎,调方法时候呢,它的这个status其实是。诶,那就你又没有抛异常,是不是我们调这个star方法嘛,然后当你诶大的这个线程以后呢,它这个状态呢,就不是零了,你要再去调大的方法呢,这时候不是零了,所以它就抛异常。说白了,这个县城啊,你就不能够让他去。迟大的多次是吧。
18:01
哎,注意啊,所以这块呢,我们注意一下啊。哎,不能让已经start的线程。啊,这个再次。啊,执行这个start的操作。是吧,哎,否则。哎,报一场。哎,这个异常的话呢,大家了解一下就行啊,就是我们这个叫非法的线程状态的异常啊。哎,就是这样一个异常,所以这个事儿的话,那就不行了啊,那既然这样不行的话呢,应该怎么做呢。对,那你得重新再创建一个对象吧。这个类还用再去重新造一个吗?不用了是吧类还用一个就行,因为你做的事一样啊,所以我们需要做的事呢,仅仅是这样啊CTRLC诶拿过来这个呢叫T2,然后让这个T2呢,咱们去调一下这个四大的方法。哎,这么着啊,然后呢,我们再去做一个。好,那么这时候的话呢,它的默认的先证名呢,其实大家也能猜到了,你造的第二个对象是吧,这个呢,是就是S杠一了。
19:08
没问题吧?对,这不就一次他们三个线程啊,目前呢,相互之间的一个交互执行,诶这样一个场景。好,这呢就是我们线程创建的第一种方式啊,这就说清楚了。好,那么这个方式说完之后呢,咱们在讲第二种方式之前,先呢,做一个练习吧,哎,这个练习呢,就在这儿,哎看看大家会不会做正呢,要求呢,创建两个分线程,其中一个线程呢,便利100以内的偶数,另一个线程呢,便利100以内的奇数。此时,两个县城做的事儿不一样。这,这咋办?啊,那这块我们这个RA方法里边执行的这个方法体不一样了呀。嗯。两个分线程啊,就是我们这块呢,就不要用主线程了。你看两个线程直线的事不一样,那你就写俩run,写俩run就意味着你要生命两个类了吧。
20:06
对啊,他俩做的事儿如果要一样的话呢,你就写一个类,就像我们刚才一样,现在不一样了,是不是就到俩类就行。诶,对啊,就是这块的思路呢,打开一下,所以这块呢,比如我们也叫做print number的一个测试哈,在这里边的话呢,我们可以呢,诶我写到前边吧,首先呢,我们class一下,比如说是这个偶数啊,Even的一个。啊,Number。Print吧,让他呢去继承于我们的这个thread。哎,这么着,然后呢,我们去重启这个run方法,这里边呢,我们写个for循环。这个呢,咱们让它从一开始啊,小于等于。才100。哎,在这我们写个if是吧,I呢,哎,曲目二相等于零。哎,这打印一下这个呢,咱们也把这个县成名呢,看一下吧。Current get一个name。哎,冒号一下。哎,加上我们这个I好,这个呢,是我们当前这个要打印偶数啊。
21:07
那接着的话呢,我们再去声明一个类啊,CTRLC。这个呢,奇数。记住,这个叫all是吧?用于打印技术。哎,就好,把这个位置呢改成不等于。哎,这这就可以了,行,然后呢,下边我们在这个main方法当中,咱们就各自创建啊,相对应的类的对象。这个呢,我们叫T1这个线程。那就它了,呃,然后呢,你再创建下边这个。他的一个实力。哎,这么着,然后呢,T一点第二个四大方法。然后再来T2点,第二个四大方法,诶这就妥了,这块呢,为了你要好区分的话呢,咱们比如换成这个箭头。哎,这么着指一下啊,好,这块我们做一个run。行,这长我们就出来了啊,那一个线程呢,是用于打印这个偶数的,哎,另外一个线程是来打印这种基数的啊,这种交互的一个执行,哎,这交互的效果还挺好是吧。
22:09
成交替了啊。行,这就完事了,大家呢,运行的效果跟我这儿不一定一样,他每次都有随机性啊。嗯,这个呢就完了,这呢算是一种比较标准的写法,咱们前面还讲过,是不是叫匿名子类的方式啊,哎,那咱们整一个看看大家还记不记得啊,这呢算作是咱们的叫方式一吧。然后下边来一个方式二。哎,放这啊放这儿的话呢,我们就要提供TH的这个子类的对象了是吧。我就直接尿。Ad,而且是匿名类。然后呢?大括号是吧。哎,大括号完了以后呢,这块这个对象就造造好了是吧,造好的话呢,你可以呢,去声明成叫T1。诶,然后呢,接下来通过七一呢,去调这个start。
23:02
那我是不是也可以呢?就不声明这个名了。我直接呢,就在这块呢,就。第2START了,这个看能不能行。可以是吧,好,那么在这个大括号里边呢,我们去把上面这个方法呢,给重写一下呗。哎,就这样是吧,然后呢,你再把这个CTRLC份。再粘过来,这个改成个不等于,这就是奇数的。所以上边一个下边一个这个呢,我们可以理解成了叫创建。哎,Thread这个类的子,哎,匿名子类的匿名对象是吧,然后造完这个对象以后呢,顺便呢,还把方法给调了。嗯,以后呢,如果我们有临时的一个需求大哥现场做个事儿,那我们可能都没有特别正规的这样去写,就是采用匿名的方式做了一下,就是下边这种方式好run一下。那跟前面这个呢,其实是一样的效果的啊,没问题,哎,这个我们都用的这个括号了是吧。
24:01
行,这个是小事啊,好,这呢就是我们说的这两种写法,尤其第二种大家稍微的熟悉一下。
我来说两句