进程与线程的概念和区别
*参考
https://www.cnblogs.com/zhehan54/p/6130030.html
- 概念
进程是资源(CPU、内存等)分配的基本单位,它是程序执行的一个实例。程序运行时系统就会创建一个进程,并为它分配内存资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量,线程由CPU 独立调度执行,在多个CPU环境下就允许多个线程同时运行,同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
- 线程和进程各自有什么区别和优劣呢
- 进程是资源分配的最小单位,线程是程序执行的最小单位。
- 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建数据表来维护代码段、堆栈段和数据段,因为CPU切换一个线程的花费远比进程要小得多,同时,创建一个线程的开销也比进程要小得多。
- 线程之间的通信更方便,同一进程下的线程可以共享局部变量,静态资源等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程的难题。
- 多进程程序更加健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
线程运行状态
- 基础知识
操作系统在实际运行过程中,可能有很多线程一直同时在运行。相对单个CPU 来说,同一时间运行的线程数只能是一个。但是所有线程都排队等待上一线程处理完毕后再执行下一线程,会带来很多问题,如一些非关键的线程长期占用CPU,而导致某些关键线程等待时间长等;在这种情况下,操作系统一般对CPU的使用按线程进行分配,限定每个线程的连续执行时间,也就是说,每个线程在执行一段时间后,必须释放CPU,所有线程一起按某些规则竞争CPU的下次分片使用时间。
*状态说明
- NEW
新建状态,线程创建后直到调用其start方法前都属于这个状态。 - RUNNABLE
就绪状态,线程可以被执行,但未获取到操作系统的某些资源(如第一节中所说的CPU时间分片)而导致未执行; - RUNNING
运行状态,线程正在被执行 - BLOCKED
阻塞状态,线程被阻塞从而未运行,需要等待唤醒事件的发生 - DEAD
死亡状态,表示线程执行完毕
-
状态转换说明
线程状态转换图
- 新建->就绪
当线程调用start方法时,从新建(NEW)状态过度到就绪(RUNNABLE)状态; - 就绪->运行
当线程在就绪状态时,如果获取到了足够的操作系统资源(如CPU等),它将会从就绪状态进入到运行状态,这个过程是由操作系统进行调度的,开发人员不能也无需处理这种状态的转换。 - 运行->就绪
当线程在运行过程中,当前所分配的操作系统资源(如CPU时间片等)使用完毕,则会由运行状态转换到就绪状态。
此过程也是由操作系统调度控制,开发人员一般无需关注。除非某些场景下CPU等操作系统资源不够导致线程执行时间变长时,可以考虑对操作系统的某项受限资源进行扩展以提高效率。
开发人员也可以通过Thread.yeild方法放弃当前的资源,此时操作系统将重新选择线程执行,当前线程的状态也会从运行转换成 就绪;但也有可能操作系统立即选择了刚放弃的线程再次执行。 - 运行->阻塞
线程运行过程中,如果遇到以下事件将会进入阻塞状态:
调用wait方法
调用Thread.join方法
调用Thread.sleep方法
调用某个Condition的await方法
调用锁的lock类方法 - 阻塞->就绪
线程在阻塞状态时,根据其阻塞的原因,如果遇到对应的某些事件发生,则会由阻塞状态进入就绪状态。
如它阻塞的原因是调用锁的lock方法,那么在获取到锁时将会进入就绪状态。 - 运行->死亡
当线程执行完毕时,会由运行状态跳转到死亡状态。
网友评论