进程:正在运行中的程序(进程是驻留在内存中的)
使用jdk自带的工具,jconsole查看当前Java进程中的所有线程。
new Thread对象,操作不创建线程。(说的线程指的是 系统内核里的PCB)
调用start才是创建PCB,才是有货真价实的线程的。
线程:进程中的单个顺序控制流,也可以理解成是一条执行路径。
PCB(Process Control Block)进程控制块:描述控制进程的运行,系统中存放进程的管理和控制信息和数据结构。
PCB一般包括:
同一个进程里的若干个PCB pid相同。不同进程的pid是不同的
PCB不是”简称“是一个数据结构,体现的是 进程/线程是如何实现的,如何被描述的。
PCB对应的是线程
一个线程对应多个PCB
如果一个进程只有一个线程,就是一个进程对应一个PCB了。
线程安全问题:罪魁祸首——抢占式执行,随机调度。
本质上还是系统里的线程的封装,每个Thread的对象就对应到系统中的一个线程,也就是PCB
start 和 run 区别:
进程和线程:
进程包含线程,要想看到线程,要先找到对应的进程,再看进程里有哪些线程。
实现线程方法
1、继承Thread,重写 run
接口比抽象类更进一步,抽象类接口则不行,要求方法都是抽象方法。
2、实现Runnable接口 实现一个interface
解耦合,目的就是为了让线程和线程要干的活 之间分离开。
未来改代码,不用多线程,或者线程池,或者协程……此时代码改动较小。
3、使用匿名类,继承Thread
创建了一个Thread的子类。(子类没有名字)所以才叫做匿名。
创建了子类的实例,并且让 t 引用执行实例
4、使用匿名内部类,实现Runnable
这个写法和2本质相同,只不过把实现Runnable任务交给匿名内部类的语法。
此处是创建了一个类,实现了Runnable,同时创建了类的实例,并且传给Thread的构造方法。
5、使用Lambda表达式(最简单,推荐写法)
把任务Lambda表达式来描述
直接把Lambda传给Thread构造方法
(匿名内部类被重写方法的形参列表)-> {
被重写方法的方法体代码
}
lambda 表达式只能简化函数式接口匿名内部类的写法形式,且接口中有且仅有一个抽象方法
上述方法,只是语法规则不同,本质上都是一样的方式,这些方式创建处理啊的线程都是一样的。
抽象类与普通类的区别