1. 多进程
现代化操作系统都是采用「多任务」和「分时」设计,从而诞生了「程序」和「进程」的概念,而后又进一步诞生了「线程」的概念。
提示
从历史的时间线来看,先诞生的是「进程」概念,后诞生的「线程」概念。
通俗地说,「程序」是死的,「进程」是活的。进程就是活着的程序。
程序是在硬盘上,而进程是程序运行起来后的、在操作系统中的所有的相关内存数据和资源。
电脑关机后,程序还在,但是进程就没了。
「进程」是程序的一次动态执行的过程,它对应了从代码加载、执行至执行完毕的一个完整过程。这个过程也是进程从产生、发展至消亡的过程。
在操作系统的管控下,多个进程「轮流」使用 CPU 资源( 和其他公共资源 )。
提示
通俗地说,站在 CPU 的角度而言,根本不存在所谓的同时。这一点很重要!
进程的特点:
进程是操作系统运行程序的基本单元;
每一个进程都有自己独立的一块内存空间和一组系统资源;
每一个进程的内部数据和状态是完全独立的。
2. 进程的状态
进程是有状态的,进程的状态反映了此时此刻是操作系统中的哪个进程在使用 CPU 。
不同的操作系统因为各有特色、各有偏重,导致大家的就能成的状态的数量互有多少。但是所有的操作系统的进程的状态都是围绕如下的、核心三态进行设计、实现的。
状态 | 说明 |
---|---|
Running 运行中 | 表示当前正式这个进程使用 CPU ,也就是说,此时此刻,这个程序的代码正在刷刷刷地执行着。对于单核 CPU 而言,一个进程中无论有多少线程,任意时刻有且仅有一个线程是处于该状态。同理,对于多核 CPU 而言,N 核 CPU 有且仅有 N 个线程处于这种状态。 |
Runnable 可运行 | 因为 CPU 是被进程轮流使用的,那么当下没有「轮到」的进程都是处于 Runnable 状态。通俗的说,这种状态就是「万事俱备,只欠东风」,这里的「东风」指的就是 CPU 。显而易见,任何时刻,大多数进程都是处于这种状态。 |
Blocked 阻塞状态 | 一个正在运行( Running )的进程因为某种原因代码逻辑无法再继续运行下去了,就进入阻塞状态。进入阻塞状态的线程会让出 CPU ,因为即便它强占 CPU 也无法再继续运行下去。当造成该线程阻塞的原因消除后,该线程将又有机会运行。通俗的说,这种状态就是『除了欠东风,还欠别的』,比如,获得用户的输入,但是用户又迟迟没有输入时。 |
在上述的核心三态之外,你可能还会经常听到、见到 2 种状态:
状态 | 说明 |
---|---|
Created 新生态 | 进程刚被创建出来的一段时间内,就是这种状态。 |
Zombie 僵尸态 | 进程在结束执行后的一段时间内,会是这种状态,直到操作系统回收为它分配的资源,将它彻底销毁。 |
以上就是经典操作系统原理中的 5 种进程状态。
3. 多线程
提示
线程是更现代化的概念和技术( 它的诞生晚于进程 )。
线程是进程中的一个单位,即,一个进程可以有多个线程( 至少有一个 )。简单来说,进程和线程的数量关系是一对多的关系。
进程是操作系统分配资源的最小单位,一个进程下的所有线程共享这个进程的所有资源。其中最关键的资源就是「时间片」,即,使用 CPU 的资格和时长。
- 进程下的某个线程是 running ,进程就是 running ;
- 进程下的所有线程是 blocked ,进程就是 blocked ;
- 进程下的 running 线程变成 blocked ,操作系统选择同进程下的 runnable 线程执行;
- 进程的本轮时间片耗完时,进程的 running 线程会变为 runnable 。操作系统选择其它进程的某个 runnable 线程运行。
通俗地说,每一个线程都有自己的「历史使命」:执行一个方法。线程开始执行,即意味着执行这个方法的第一行代码;方法的最后一行代码结束后,线程则会被销毁。
每一个线程所要执行的那个方法就被称为线程的「执行方法」,也叫「入口方法」。
每一个进程天然、天生、自动拥有一个线程,这个线程以 main 方法作为自己的执行方法,因此,这个线程也被称为 main 线程,即,主线程。
创建并使用线程的过程可以分为 4 个步骤:
定义一个线程类,同时指明这个线程的执行方法
创建线程对象
启动线程
终止线程
定义一个线程类通常有两种方法:继承 java.lang.Thread 类和实现 java.lang.Runnable 接口。