文章目录

  • 1. 并行和并发有什么区别?
  • 2. 什么是进程和线程?
  • 3. 程序开发时为什么要用多线程,单线程不是很好吗?多线程有什么意义?
  • 4. 在什么场景下使用多线程技术?


1. 并行和并发有什么区别?

并发和并行都可以处理“多任务”,二者的主要区别在于是否是“同时进行”多个的任务。

并行:指多件事情在同一时刻发生;比如:A事情和B事情同时进行;
并发:指多件事情在同一时间间隔内发生;比如:操作系统将CPU的时间片分时让给A事情和B事情,仿佛是同时执行;

(1) 并发:

在单核CPU下,线程实际上还是串行执行的,操作系统中有一个组件叫任务调度器,将CPU的时间片(Windows下时间片最小为15ms)分给不同的程序使用,只是由于CPU在线程间切换非常快(时间片很短),人们感觉是同时运行的。一般会将这种轮流使用CPU的做法叫做并发。

CPU

时间片1

时间片2

时间片3

时间片4

core

线程1

线程2

线程3

线程4

同一时刻只能有一条指令执行,把时间分成若干段,使多个进程快速交替的执行:

java中的并发与数据库的并发区别在哪 java并发与并行的区别_java

(2) 并行:在多核CPU下,每个核(core)都可以调度运行线程,这时候线程是并行的。

CPU

时间片1

时间片2

时间片3

时间片4

core1

线程1

线程1

线程3

线程3

core2

线程2

线程4

线程2

线程4

同一时刻,多个指令可以在多个处理器上同时执行:

java中的并发与数据库的并发区别在哪 java并发与并行的区别_java中的并发与数据库的并发区别在哪_02


(3) 并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在。

应用程序可以是并发的,但不是并行的,这意味着它可以同时处理多个任务,但是没有两个任务在同一时刻执行。
应用程序可以是并行的,但不是并发的,这意味着它同时处理多核CPU中的任务的多个子任务。(两个执行的线程不会抢占CPU时间片)
应用程序可以既不是并行的,也不是并发的,这意味着它一次一个地处理所有任务。
应用程序可以既是并行的也是并发的,这意味着它同时在多核CPU中同时处理多个任务。(两个执行的线程会抢占CPU时间片)

操作系统的并发性是指在计算机系统中”同时“运行着多个程序,这些程序宏观上是同时运行的,微观上是交替运行的。

注意:在单CPU的计算机中,其实并没有真正的并行,它只不过是CPU时间钟快速轮转调度带给你的错觉,而这种错觉让你产生了它们真的在同一时刻同时运行。当然如果是多核CPU,那么并行运行还是真实存在的。

单核CPU同一时刻只能执行一个程序,各个程序只能并发的执行。

多核CPU同一时刻可以执行多个程序,多个程序可以并行的执行。

2. 什么是进程和线程?

如下图,使用进程查看软件Process Explorer(Windows任务管理器也可以)来查看系统中的进程和线程,首先看到的就是系统进程的列表,列出了操作系统中当前运行的所有进程(运行中的程序)。列表的每一行对应每个进程的详细信息,并且列出了所占用的系统资源,包括CPU、内存、磁盘、线程数等。

java中的并发与数据库的并发区别在哪 java并发与并行的区别_java_03

1、进程:

(1) 什么是进程呢?

简单来说,进程是程序的一次启动和执行。上图中运行在内存中的exe文件就可以 理解为进程,进程是受操作系统管理的基本运行单元,是操作系统进行资源分配和调度的基本单位。

操作系统在分配资源时是把资源分配给进程的,但是CPU资源比较特殊,它是被分配到线程的,因为真正要占用CPU运行的是线程,所以也说线程是CPU分配的基本单位。

(2) 什么是程序呢?

程序是存放在硬盘中的可执行文件,主要包括代码指令和数据。一个进程是一个程序的一次启动和执行,是操作系统将程序装入内存,给程序分配必要的系统资源,并且开始运行程序的指令。

程序是指令序列,这些指令可以让CPU做指定的任务。*.java程序经编译后形成*.class文件。在IDE中运行*.class文件相当于在操作系统中启动一个JVM虚拟机进程,在该虚拟机进程中加载*.class文件并运行,*.class文件通过执行创建其他新线程的代码来执行具体的任务。

(3) 进程与程序是什么关系呢?

同一个程序可以多次启动,对应多个进程。比如,多次打开Chrome浏览器程序,在Process Explorer中可以看到多个Chrome浏览器进程。

2、线程:

(1) 有了进程,为何又出现线程?

早期的操作系统只有进程而没有线程。进程是程序执行和系统进行并发调度的最小单位。随着计算机的发展,CPU的性能越来越高,从单核CPU发展到了多核CPU,性能提升了成千上万倍。为了充分发挥CPU的计算性能,提升CPU硬件资源的利用率,同时弥补进程调度过于笨重产生的问题,进程内部演进出了并发调度的诉求,于是就发明了线程。

(2) 什么是线程?

线程可以理解为在进程中独立运行的子任务,比如QQ.exe运行时,很多子任务也同时在运行,如好友视频线程、下载文件线程、传输数据线程、发送表情线程等,这些不同的任务或者说功能都可以同时运行,其中每一项任务完全可以理解成是“线程”在工作,传文件、听音乐、发送图片表情等这些功能都有对应的线程在后台默默地运行。

线程是指“进程代码段”的一次顺序执行流程。线程是CPU调度的最小单位。一个进程中有多个线程,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器和栈区域。

3、进程和线程的区别:

现在几乎百分之百的操作系统都支持多任务的执行,对计算机来说每一个任务就是一个进程(Process),在每一个进程内部至少要有一个线程(Thread)是在运行中,有时线程也称为轻量级的进程。

(1) 线程是“进程代码段”的一次顺序执行流程。一个进程由一个或多个线程组成,一个进程至少有一个线程。

(2) 线程是CPU调度的最小单位,进程是操作系统分配资源的最小单位。线程的划分尺度小于进程,使得多线程程序的并发性高。

(3) 线程是出于高并发的调度诉求从进程内部演进而来的。线程的出现既充分发挥了CPU的计算性能,又弥补了进程调度过于笨重的问题。

(4) 进程之间是相互独立的,但进程内部的各个线程之间并不完全独立。各个线程之间共享进程的方法区内存、堆内存、系统资源(文件句柄、系统信号等)。

(5) 切换速度不同:线程上下文切换比进程上下文切换要快得多。所以,有的时候,线程也称为轻量级进程。

3. 程序开发时为什么要用多线程,单线程不是很好吗?多线程有什么意义?

(1) 实现异步调用:

从调用角度来讲,如果需要等待结果返回才能继续运行,就是同步;如果不需要等待结果返回就能继续运行就是异步;

多线程可以让方法执行变成异步的(即不要干巴巴的等着),比如说读取磁盘文件时,假如读取操作话费了5秒钟,假如没有线程调度机制,那么这5秒钟CPU什么也做不了,其他代码都得暂停。。。

比如在项目中视屏文件需要转换格式等操作比较耗时,这时可以开一个新线程处理视屏转换,避免阻塞主线程。

其实如果大家有使用“多任务操作系统”的经验,比如Windows系列,那么对它的方便性应该都有体会:使用多任务操作系统Windows可以大幅利用CPU的空闲时间来处理其他任务,比如可以一边让操作系统处理正在用打印机打印的数据,一边使用Word编辑文档。CPU在这些任务中不停地切换,由于切换的速度非常快,给使用者的感受就是这些任务在同时运行,所以使用多线程技术可以在同一时间内做更多不同种类的任务。

使用多个线程有助于在单处理器系统上获得更高的吞吐率。如果程序是单线程的,那么当程序等待某个同步I/O操作完成时,处理器将处于空闲状态。而在多线程程序中,如果一个线程在等待I/O操作完成,另一个线程可以继续运行,使程序能够在I/O阻塞期间继续运行。(这就好比在等待水烧开的同时看报纸,而不是等到水烧开之后再开始看报纸)。

(2) 充分利用多核CPU的优势,提高运行效率:只有多核CPU才能提高效率,单核CPU仍然是轮流执行。

由于基本的调度单位是线程,因此如果在程序中只有一个线程,那么最多同时只能在一个处理器上运行。在双处理器系统上,单线程的程序只能使用一半的CPU资源,而在拥有100个处理器的系统上,将有99%的资源无法使用。另一方面,多线程程序可以同时在多个处理器上执行。如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率。

比如下面的场景,执行3个计算,最后将计算结果汇总:

计算1,花费10ms
计算2,花费11ms
计算3,花费9ms
汇总计算,花费1ms

如果是串行执行,那么总共花费的时间为:10+11+9+1=31ms

但是如果是四核CPU,各个核心分别使用线程1执行计算1,线程2执行计算2,线程3执行计算3,那么这3个线程是并行执行的,花费的时间只取决于运行时间最长的那个线程,最后加上汇总时间只花费12ms。

因此结论为:

在单核CPU下,多线程不能实际提高程序的运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用CPU,不至于让一个线程总占用CPU,别的线程没法干活。

在多核CPU下,可以并行跑多个线程,但是能够提高效率也要视情况而定,只有有些任务经过精心设计,将任务拆分并行执行才可以提高程序的运行效率。

4. 在什么场景下使用多线程技术?

(1) 阻塞:一旦系统中出现了阻塞现象,则可以根据实际情况来使用多线程提高运行效率。

(2) 依赖:业务分为两个执行过程,分别是A和B,当A业务有阻塞的情况发生时,B业务的执行不依赖A业务的执行结果,这时可以使用多线程来提高运行效率;如果B业务依赖A业务的执行结果,则不需要使用多线程技术,按顺序串行执行即可。

注意多线程是异步的,所以千万不要把IDE里代码的顺序当作线程执行的顺序,线程被调用的时机是随机的。