Java编程那些事儿系列文章(全集目录)
第十二章 多线程
当计算机处于DOS时代时,程序几乎是没有界面的,而且由于计算机运行速度等原因,那个时代的计算机只能启动一个程序,只有当该程序退出以后才可以执行其它的程序。但是随着计算机性能的提高,以及软件的丰富,如果计算机还只能同时执行一个程序的话,那么计算机恐怕是很多人都不能接受的。
这种在任何一个时间点,可以有多个程序同时执行,或者有多个程序逻辑同时执行的能力,成为并发执行。
现在计算机早已进入到并发执行的时代,对于程序编程来说,进行并发执行的程序编写也就被称作并发编程,在Java语言中,同一个程序内部的并发处理由线程这个概念来实现。
12.1 多线程简介
从小时候开始,老师就教育大家——“一心不可二用”,这是指做一件事情的时候一定要专注,不能够分心。但是在程序编程的领域却早已经需要做到“一心二用”甚至“一心多用”了。下面来看一下线程的概念吧!
12.1.1 进程和线程
在介绍线程的概念以前,首先介绍一下进程的概念。
进程(Process)指操作系统中一个独立运行的程序。例如在计算机中,同时运行着QQ、Word、MSN等,那么QQ程序是一个进程,MSN程序也是一个进程。在Windows操作系统中的任务管理器中,就可以清晰的看到当前操作系统中正在运行的进程信息。
进程,也称任务,所以支持多个进程同时执行的操作系统就被称作多进程操作系统或多任务操作系统,现在主流的操作系统都属于这种类型。在操作系统中,每个进程拥有独立的内存空间等系统资源,进程和进程之间的系统资源不互用,所以进程之间的通信比较麻烦。通过在操作系统上同时运行多个进程,可以充分发挥计算机的硬件能力,更方便用户使用,也使得各种各样的程序大量出现。
对于只有一个CPU的计算机来说,是如何实现同时执行多个进程的呢?其实CPU采用的原理就是分时执行,每个进程处于操作系统的进程队列中。然后每个进程依次获得一个时间片进入CPU进行执行,在该时间片执行完成以后,该进程保存自身状态,退出CPU,然后其它的进程进入CPU继续执行。由于时间片的时间很短,例如Windows操作系统的时间片是20ms,所以在计算机用户看来程序就是同时执行的,而实际的执行方式是穿插依次执行的。而对于多CPU的计算机来说,只是排队的队列增加了几个而已,每个队列的实现方式和上面的介绍类似。
但是进程的概念相对比较大,而且需要成为一个独立的程序,这样对于编程来说比较麻烦,所以在程序开发中设计了另外一个概念——线程。
线程(Thread)指同一个程序(进程)内部每个单独执行的流程。在前面的程序中每个程序内部都只包含一个系统流程,该流程从main方法开始,随着方法的调用进入到每个方法的内部,在方法调用完成以后返回到调用的位置,直到main方法结束以后则该流程结束,这个流程就是前面程序中的系统线程。Java语言对于线程的概念提供了良好的支持,在编程中实际使用线程也显得比其它语言要简单一些。
而在实际实现时,Java语言支持在一个程序内部同时执行多个流程,其中每个单独的流程就是一个线程。例如在QQ程序中,系统的线程负责响应用户的按键操作,在后台可以启动网络通讯的线程执行数据的发送和接收,这样两个流程之间同时执行,并协调进行工作。而在服务器端程序中,每个和服务器进行通讯的客户端,在服务器端都会启动一个对应的线程进行通讯,这样每个客户端才显得同时和服务器端进行通讯。
在很多地方,线程被看作是一种“轻量级进程”,因为使用线程和进程的改变比较类似,而且使用线程时对于系统资源,如内存、CPU等,的占用要比进程小很多,也就是有更小的系统开销。另外,同一个程序中的线程之间变量是共享的,线程之间的数据交换要比进程之间的数据交换简单一些。
总之,无论是进程的概念还是线程的概念,都使编程从串行编程(依次执行)进入到并行编程(同时执行)的领域,而在CPU内部实现的原理都是按照时间片进行切换。