一.
既然是创建线程,那么线程应该怎么创建?在没有学习java之前,这些程序是谁在操作执行的呢?是由我们所在的操作系统来完成的。Windows里面有个任务管理器,它来管理这些任务,它来创建这些进程,并来创建进程中所用的线程。是由系统来完成的,我们无法直接使用系统来帮我们做这件事情。解决问题的时候,首先想到的是java中是否有给我们提供能解决该问题的对象,尤其是线程还走了系统。你不玩java,它没有多线程,因为windows具备这能力,它在帮你做这个分配呢。我们是做不了的,我们就想说java是否也有这样的对象,来找底层做这件事情,并把对象暴露出来给我们用呢。我们做事情解决问题,要先找对象。(找到线程对象么?是的,线程对象来做执行动作,就不需要我们来操作了)
那么这对象是谁呢?我们到java的API文档里来查阅一下。在java的核心包里面,java.lang(java语言包)。为什么要找核心包,是因为虚拟机一启动,就带着多线程,所以对象就在这呢(控制多线程的对象在核心包里,因为从这发起的)。Java.lang包里有这么一个对象thread
这个线程,我们知道有这么一个thread类(原来thread类就代表着线程)。咋创建呢?
学习对象的时候吧,如果没有人教授,就要阅读API文档。
在API文档中,还有一个使用thread方法的示例,里面有构造函数和复写的run方法。(虽然有两种方法,但是只介绍了一种创建执行路径方法)
(梳理一下,要想创建新的线程,先要继承thread类,然后复写其中
的run方法)
为什么要重写run方法呢?
这里要介绍创建线程的第一种方式,
继承thread类是理解的(继承是为了具备父类的特性-创建线程),为什么要覆盖run方法?
Thread类中的组成如下,有构造器,
同时thread类并不是抽象的,(说明thread可以创建对象),它能new对象。问题解决了,java已经给我们提供了thread类,而且创建其对象就是线程(这句话怎么得出来的?因为thread对象就是线程),这就可以了,为什么要依据API文档中的继承,覆盖什么的。
创建thread对象,就是创建线程对象。
创建线程的目的是什么?创建线程的目的是为了开启一条执行路径,开启执行路径的目的是为了什么?是为了让一部分代码和其他代码同时运行,而这部分代码我们称之为任务。这就是刚才一直在分析的特点。
任务是一段代码,这段代码要被封装了才能用。这个封装体就是run方法。这个才是thread类里面有run方法的原因。
有人说,直接new对象,调用run方法就完事儿了。这么讲没错,但是你那run方法里面的任务是我需要的吗?(这就是复写的原因)
我们开启线程的目的是为了运行我们定义的任务,你有任务函数,我有任务内容,该怎么办?就应该继承你,并覆盖你,把我的内容写到你的run方法里面去。这就是我们为什么继承并复写run方法的原因。
(用子类继承thread类,就是为了覆盖父类中的run方法,来运行自己想要运行的内容)
因此,就不再做新建thread对象的操作了,而是继承操作了。
根据之前的例子,卡在循环这,我们必须要重开一个线程运行循环语句。本节讲述到现在,就为了介绍如何将循环语句,引入新建的线程。
(这是另一种形式的循环语句引入run方法)
到目前为止,覆盖完了。第三步就是创建线程对象,搞一个类,继承thread,thread是线程,继承它,我也是线程(继承它的所有特点)。
→我知道了,为什么要创建子类对象了,光有继承的子类,覆盖的run方法,没有用。必须有对象才能调用方法运行。
现在修改了主程序中的代码,对象在调用run方法。这个时候,无论是d1还是d2都是线程,
编译运行的结果,依旧是之前的那样。
为什么会这样呢?为什么还是主线程在这行呢?(怎么知道是主线程执行的呢?)试想一下,如果真的是有两个线程被创建了,它们要如果运行起来了,就意味着d1和d2运行run方法,这两个有可能随机。
现在修改一下程序,在两个循环之间加上输出语句。看看他们是不是有序的。
结果显示,两个循环输出还是固定有序的。说明到目前为止,还是只有一个主线程在执行。为什么呢?线程这类事物比较特殊,创建完以后,你去调用这个run方法,其实跟我们之前创建对象调用方法一点区别也没有。这是一个标准的常规调用方式,如果你想要使用线程做这件事,你得到线程类当中去找方法。
在示例的后面,还有一句话,然后….创建并启动一个线程。这个thread继承子类对象创建了不好使,还得启动。
谁做开启动作,start方法。怎么开启,线程自己最清楚(所以到线程类中寻找相应的方法),
用手工调用run方法吗?不用,直接start就可以了。
Start方法做了两件事儿,一是开启线程,二是调用run方法,告诉虚拟机调用该方法。
经过前面的实例讲解,调用run和调用start有什么区别?
这会运行的结果终于符合我们原先的设想了。Cpu在做随机的切换,(因此两个结果是随机的),我们这里有三个线程(两个循环线程,将主线程抛开),主线程和自己开启的俩。Cpu在三个线程间快速的做着切换,切到谁运行谁,所以是随机的。结果怎么打印,怎么输出是cpu说了算。