讲述下面的内容之前,先来回顾一下一个重要的知识点
进程和线程之间的区别
1.进程包括线程。
2.进程有自己独立的内存空间和文件描述符表。同一个进程中的多个线程之间,共享同一份地址空间和文件描述符表。
3.进程是操作系统资源分配的基本单位,线程是操作系统调度执行的基本单位。(非常重要的概念)
4.进程之间具有独立性,一个进程挂了,不会影响到别的进程。同一个进程里的多个线程之间,一个线程挂了,可能会把整个进程带走,影响到其他线程的。
接下来进入本文的主要内容.
目录
1. 创建线程
1.1 继承 Thread 类
1.2 实现 Runnable 接口
1.3 使用匿名内部类(lambda表达式)
2.Thread 类
1. 创建线程
首先这里,先纠正一个问题,多线程和多进程在我们的电脑中是同时存在的,并不是多线程就替代了多进程.
1.1 继承 Thread 类
创建一个类,然后继承Thread类,然后重写Thread的run 方法.
回顾重写与重载:
方法重载?overload
方法重写?override
方法重载:发生在当前类,是对当前类中的方法进行扩展。方法名称相同,参数的类型或个数不同。
方法重写:发生在子类,是子类对父类方法的扩展。方法名称、参数类型、返回值类型全部相同。
具体可参考:
重写和重载https://blog.csdn.net/weixin_46114074/category_12210388.html?spm=1001.2014.3001.5482
run叫做入口方法,不叫构造。
run是特殊的方法,重写了父类的方法,然后这个方法就会被java自动执行到了。随便写一个方法只能是普通的方法,没有特殊含义。run是特殊方法,是能被自动调用到的。其他方法是普通方法,要我们手动调用。我们无法区分是并行还是并发,都有可能。
创建线程的实例然后使用start进行启动线程.
这个代码涉及到两个线程。
1.main方法所对应地线程(一个进程里至少有一个进程),也可以称为主线程
2.通过t.start创建的新的线程。
点击这里运行程序,其实是idea对应的进程,创建了一个新的java进程,这个java进程来执行咱们自己写的代码。这个java进程里就有两个线程,一个是main,一个是myThread。
运行结果:
进行交替输出,达到了多线程的结果.
1.2 实现 Runnable 接口
创建一个类, Runnable 接口
2.实例化这个类,将这个实例作为参数传入到Thread 的实例中. 调用start方法.
1.3 使用匿名内部类(lambda表达式)
创建线程最推荐的写法:使用lambda表达式。这是最简单最直观的写法。
lambda表达式,本质上是一个匿名函数。(没有名字的函数,一次性的。)Java里面,方法是无法脱离类的。在Java里面,lambda就相当于一个例外。
lambda表达式的基本写法。()里面放参数,如果只有一个参数,()可以省略。如果{}里面放函数体,写各种java代码了。如果这里只有一行代码,也可以省略{}。
2.Thread 类
每个线程都有一个唯一的Thread对象与之关联。
Java代码中的Thread对象和操作系统中的线程是一一对应的。
Thread(String name)中的name参数,是给线程起了一个名字。这里的名字,不影响程序执行,只是方便咱们在调试的时候,快速找到咱们关心的线程。
每个线程都有自己的状态,优先级,上下文,记账信息。(之前提到的这些属性,都是线程的。只不过之前谈到的进程是属于只有一个线程的进程)
1.idDaemo(): 如果true,表示后台线程。如果false,表示前台线程。
前台线程会阻止java进程结束。必须要java进程中所有的前台线程都执行完,java进程才能结束。而后台线程不阻止java进程结束。哪怕后台线程还没执行完,java进程该结束就结束了。创建的线程默认是前台的。可以通过setDaemon设置成后台。
2.isAlive():描述系统内核里的那个线程是否存活的。线程的入口方法执行完毕,此时系统中的对应线程就没有了。