一、多线程介绍
多线程是Java语言的重要特性,大量应用于网络编程、服务器端程序的开发,最常见的UI界面底层原理、操作系统底层原理都大量使用了多线程。
我们可以流畅的点击软件或者游戏中的各种按钮,其实,底层就是多线程的应用。UI界面的主线程绘制界面,如果有一个耗时的操作发生则启动新的线程,完全不影响主线程的工作。当这个线程工作完毕后,再更新到主界面上。
我们可以上百人、上千人、上万人同时访问某个网站,其实,也是基于网站服务器的多线程原理,如果没有多线程,服务器处理速度会极大降低。
在学习多线程之前,我们先要了解几个关于多线程有关的概念。
程序
程序(Program)是一个静态的概念,一般对应于操作系统中一个可执行文件,比如:我们要启动酷狗听音乐,则对应酷狗的可执行程序。当我们双击酷狗,则加载程序到内存中,开始执行该程序,于是产生了“进程”。
进程
进程(Process)是一个动态的概念,将程序加载进入内存中,则就产生了一个进程。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
现代的操作系统都可以同时启动多个进程。比如:我们在用酷狗听音乐、也可以使用idea写代码、也可以同时用浏览器查看网页。
多进程有什么意义呢?
单进程的计算机只能做一件事情,而我们现在的计算机都可以做多件事情。例如,一边玩游戏(游戏进程),一边听音乐(音乐进程)。
也就是说现在的计算机都是支持多进程的,可以在一个时间段内执行多个任务。并且,还可以提高CPU的使用率。
线程
线程是进程中的一个执行单元,负责当前进程中任务的执行,一个进程中至少有一个线程,也可以有多个线程。
什么是多线程呢?即就是一个程序中有多个线程在同时执行,我们也称之为多线程程序。
紧接着,我们来区别单线程程序与多线程程序的不同:
- 单线程程序:若有多个任务只能依次执行。当上一个任务执行结束后,下一个任务才开始执行。
- 多线程程序:若有多个任务可以同时执行。多个任务可以并发执行,每个线程都执行一个任务。
Java程序的运行原理
由java命令启动JVM,JVM启动就相当于启动了一个进程,该线程在负责java程序的运行,而且这个线程运行的代码存在于main方法中,我们把这个线程称之为主线程。
JVM虚拟机的启动是单线程的还是多线程的? 答案是多线程。原因是垃圾回收线程也要先启动,否则很容易会出现内存溢出。现在的垃圾回收线程加上前面的主线程,最低启动了两个线程,所以,JVM的启动其实是多线程的。
二、线程调度策略
如果多个线程被分配到一个CPU内核中执行,则同一时刻只能允许有一个线程能获得CPU的执行权,那么进程中的多个线程就会抢夺CPU的执行权,这就是涉及到线程调度策略。
分时调度
所有线程轮流使用CPU的执行权,并且平均的分配每个线程占用的CPU的时间。
抢占式调度
让优先级高的线程以较大的概率优先获得CPU的执行权,如果线程的优先级相同,那么就会随机选择一个线程获得CPU的执行权,而Java采用的就是抢占式调用。
三、并发和并行
在学习多线程之前,我们必须先理解什么是并发,什么是并行,什么是并发编程,什么是并行编程。
并发(concurrency)
使用单核CPU的时候,同一时刻只能有一条指令执行,但多个指令被快速的轮换执行,使得在宏观上具有多个指令同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干端,使多个指令快速交替的执行。
如上图所示,假设只有一个CPU资源,线程之间要竞争得到执行机会。图中的第一个阶段,在A执行的过程中,B、C不会执行,因为这段时间内这个CPU资源被A竞争到了,同理,第二阶段只有B在执行,第三阶段只有C在执行。其实,并发过程中,A、B、C并不是同时进行的(微观角度),但又是同时进行的(宏观角度)。
在同一个时间点上,一个CPU只能支持一个线程在执行。因为CPU运行的速度很快,CPU使用抢占式调度模式在多个线程间进行着高速的切换,因此我们看起来的感觉就像是多线程一样,也就是看上去就是在同一时刻运行。
并行(parallellism)
使用多核CPU的时候,同一时刻,有多条指令在多个CPU上同时执行。
如图所示,在同一时刻,ABC都是同时执行(微观、宏观)。
并发编程和并行编程
● 在CPU比较繁忙(假设为单核CPU),如果开启了很多个线程,则只能为一个线程分配仅有的 CPU资源,这些线程就会为自己尽量多抢时间片,这就是通过多线程实现并发,线程之间会竞争CPU资源争取执行机会。 ● 在CPU资源比较充足的时候,一个进程内的多个线程,可以被分配到不同的CPU资源,这就是通过多线程实现并行。
至于多线程实现的是并发还是并行?上面所说,所写多线程可能被分配到一个CPU内核中执行,也可能被分配到不同CPU执行,分配过程是操作系统所为,不可人为控制。所以,如果有人问我我所写的多线程是并发还是并行的?我会说,都有可能。
总结:单核CPU上的多线程,只是由操作系统来完成多任务间对CPU的运行切换,并非真正意义上的并发。随着多核CPU的出现,也就意味着不同的线程能被不同的CPU核得到真正意义的并行执行,故而多线程技术得到广泛应用。
不管并发还是并行,都提高了程序对CPU资源的利用率,最大限度地利用CPU资源,而我们使用多线程的目的就是为了提高CPU资源的利用率。