前言
Go 语言比 Java 语言性能优越的一个原因,就是轻量级线程Goroutines
(协程Coroutine)。本篇文章深入分析下 Java 的线程和 Go 的协程。
协程是什么
协程并不是 Go 提出来的新概念,其他的一些编程语言,例如:Go、Python 等都可以在语言层面上实现协程,甚至是 Java,也可以通过使用扩展库来间接地支持协程。
当在网上搜索协程时,我们会看到:
-
Kotlin 官方文档说「本质上,协程是轻量级的线程」。
-
很多官方文档也提到「不需要从用户态切换到内核态」、「是协作式的」等等。
「协程 Coroutines」源自 Simula 和 Modula-2 语言,这个术语早在 1958 年就被 Melvin Edward Conway 发明并用于构建汇编程序,说明协程是一种编程思想,并不局限于特定的语言。
协程的好处
性能比 Java 好很多,甚至代码实现都比 Java 要简洁很多。
那这究竟又是为什么呢?下面一一分析。
进程
进程是什么
计算机的核心是 CPU,执行所有的计算任务;操作系统负责任务的调度、资源的分配和管理;应用程序是具有某种功能的程序,程序是运行在操作系统上的。
进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。
进程组成
进程由三部分组成:
-
程序
:描述进程要完成的功能,是控制进程执行的指令集。 -
数据集合
:程序在执行时所需要的数据和工作区。 -
进程控制块
:(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志。
进程特征
-
动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的。
-
并发性:任何进程都可以同其他进程一起并发执行。
-
独立性:进程是系统进行资源分配和调度的一个独立单位。
-
结构性:进程由程序、数据和进程控制块三部分组成。
线程
线程是什么
线程是程序执行中一个单一的顺序控制流程
,是程序执行流的最小单元
,是处理器调度和分派的基本单位
。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间
(也就是所在进程的内存空间)。
线程组成
-
线程ID、当前指令指针(PC)
-
寄存器
-
堆栈
任务调度
大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式
。
在一个进程中,当一个线程任务执行几毫秒后,会由操作系统的内核(负责管理各个任务)进行调度,通过硬件的计数器中断处理器,让该线程强制暂停并将该线程的寄存器放入内存中,通过查看线程列表决定接下来执行哪一个线程,并从内存中恢复该线程的寄存器,最后恢复该线程的执行,从而去执行下一个任务。
进程与线程的区别
-
线程是程序执行的最小