9:10 约会,真爱,请“星标”
1、对线程与线程
线程是什么?
是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。线程有就绪、阻塞和运行三种基本状态
多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
并行与并发:先说一下并行:多个 cpu 实例或者多台机器同时执行一段处理逻辑,是真正的同时。并发 : 通过 cpu 调度算法,让用户看上去同时执行,实际上从 cpu 操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用 TPS 或者 QPS 来反应这个系统的处理能力。
为啥使用多线程?
总之,为了解决负载均衡问题, 充分利用 CPU 资源. 为了提高 CPU 的使用率, 采用多线程的方式去同时完成几件事情而不互相干扰. 为了处理大量的 IO 操作时或处理的情况需要花费大量的时间等等, 比如: 读写文件, 视频图像的采集, 处理, 显示, 保存等
聊到多线程,多半会聊并发与并行,咋理解并区分这两个的区别呢?
- 类似单个 CPU,通过 CPU 调度算法等,处理多个任务的能力,叫并发
- 类似多个 CPU,同时并且处理相同多个任务的能力,叫做并行
在代码中:
并发:不同的代码块交替执行
并行:不同的代码块同时执行
2、线程的运行与创建
2.1 线程的创建
Java 创建线程对象有两种方法:
– 继承 Thread 类创建线程对象
– 实现 Runnable 接口类创建线程对象
新建 MyThread 对象,代码如下:
MyThread 类继承了 Thread 对象,并重写(Override)了 run 方法,实现线程里面的逻辑。main 函数是使用 for 语句,循环创建了 10 个线程,调用 start 方法启动线程,最后打印当前线程对象的 ID。
run 方法和 start 方法的区别是什么呢?
run 方法就是跑的意思,线程启动后,会调用 run 方法。
start 方法就是启动的意思,就是启动新线程实例。启动线程后,才会调线程的 run 方法。
执行 main 方法后,控制台打印如下:
可见,线程的 ID 是线程唯一标识符,每个线程 ID 都是不一样的。
start 方法和 run 方法的关系如图所示:
同理,实现 Runnable 接口类创建线程对象也很简单,只是不同的形式。新建 MyThreadBrother 代码如下:
2.1 线程的运行
在运行上面两个小 demo 后,JVM 执行了 main 函数线程,然后在主线程中执行创建了新的线程。正常情况下,所有线程执行到运行结束为止。除非某个线程中调用了 System.exit(1) 则被终止。
在实际开发中,一个请求到响应式是一个线程。但在这个线程中可以使用线程池创建新的线程,去执行任务。
3、线程的状态
新建 MyThreadInfo 类,打印线程对象属性,代码如下:
执行代码打印如下:
线程是一个对象,它有唯一标识符 ID、名称、状态、优先级等属性。线程只能修改其优先级和名称等属性,无法修改 ID、状态。ID 是 JVM 分配的,名字默认也为 Thread-XX,XX 是一组数字。线程初始状态为 NEW。
线程的状态实现通过 Thread.State 常量类实现,有 6 种线程状态:new(新建)、runnnable(可运行)、blocked(阻塞)、waiting(等待)、time waiting(定时等待)和 terminated(终止)。状态转换图如下:
线程状态流程大致如下:
各种状态一目了然,线程状态流程大致如下:
- 线程创建后,进入 new 状态
- 调用 start 或者 run 方法,进入 runnable 状态
- JVM 按照线程优先级及时间分片等执行 runnable 状态的线程。开始执行时,进入 running 状态
- 如果线程执行 sleep、wait、join,或者进入 IO 阻塞等。进入 wait 或者 blocked 状态
- 线程执行完毕后,线程被线程队列移除。最后为 terminated 状态。
4、小结
本文介绍了线程与多线程的基础篇,包括了线程启动及线程状态等。如果有神呢么问题,欢迎一起交流~