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