如果不考虑多线程的话,那么在程序只有一条执行路径,代码串行执行:顺序执行、选择或者循环。单线程就像你用你惯常的手去写字,多线程编程就要求你左手画圆,右手画方。一不留神就会手忙脚乱,圆不是圆,方也不像方。在继续学习多线程编程之前,先来小小的回顾一下操作系统的进化史。
操作系统发展回顾
手工操作:计算机并不包含操作系统,从头到尾只执行一个程序,这个程序可以访问程序中所有的资源。
批处理系统:加载在计算机上的一个系统软件,在它的控制下,计算机能够自动地、成批地处理一个或多个用户的作业(这作业包括程序、数据和命令)。
多道程序设计技术:
所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行。即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬、软件资源。当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序。
分时系统:
由于CPU速度不断提高和采用分时技术,一台计算机可同时连接多个用户终端,而每个用户可在自己的终端上联机使用计算机,好象自己独占机器一样。
从操作系统的发展可以看出来,从单任务到多任务,从多道处理到分时处理,计算机的资源利用率和并发性越来越高了。
在早期的分时系统中,每个进程相当于一台虚拟的冯·诺依曼计算机,它拥有存储指令和数据的内存空间,根据机器语言的语义以串行的方式执行指令,并通过一组I/O指令与外部设备通信。
这个时候如果把一个进程当做虚拟机,那么这个进程中的线程就相当于虚拟机中的进程啦。
串行编程的好处在于直观和简单,不容易出岔子,缺点是如果某些步骤处理时间过长需要无谓的等待;
异步处理的好处是:高效,充分利用资源,缺点各个步骤之间需要协调一致,不然容易乱套。
结论:分时,多进程、多线程的并发、异步执行,这些复杂的编程手段已经成熟了,需要我们更好地掌握以提高自己的编程水平。
多线程的优势
1. 发挥处理器的强大能力
在多处理器上,多线程可以通过提高处理器资源的利用率来提高系统的吞吐率。
在单处理器系统上也可以获得更高的吞吐率,比如说多线程程序在等待某个同步I/O操作时,还有其他线程可以继续运行。
2. 建模的简单性
完成单任务时,很简单,只要把这件事做好就行。但是在完成多任务的时候,不仅要把活干好,还要考虑不同任务之间存在优先级和时间。
3. 异步事件的简化处理
一部分线程接受客户端请求,另一部分处理器请求。如果是单线程程序的话,处理请求时会停顿导致接受请求阻塞,为了避免这个问题单线程程序必须使用非阻塞的I/O,这种I/O的复杂性要远远高于同步I/O。
4. 响应灵敏的用户界面
这个就不解释了。
多线程的例子
如果使用得当,线程可以有效地降低程序的开发和维护成本,同时提升复杂应用程序的性能。
这里列举几个多线程的应用场景,帮助加深理解。
1. 图形用户界面中,多线程可以提供用户界面响应灵敏度。
2. 服务器应用程序中,可以提升资源利用率以及系统吞吐率。比如在tomcat中一部分线程接受请求,另一部分线程处理请求。
3. JVM垃圾收集器中,垃圾收集通常在一个或者多个专门的线程中运行,同时还有个主线程来运行main方法。
4. 矩阵计算,多线程并发执行。
5. 下载大文件时,大文件可以分成多个部分,每个线程下载一部分。
6. 多叉树中搜索N个文件。
7. 假设有个请求,这个请求服务端的处理需要执行3个很缓慢的IO操作(比如数据库查询或文件查询)。
8. web服务器本身;各种专用服务器(如游戏服务器)。
9. 后台任务,例如:定时向大量(100w以上)的用户发送邮件。
10.
异步处理,例如:发微博、记录日志等。
11.
分布式计算。
12. 生产者和消费者模型。
13. 定时任务。
14. Servlet和JSP,多并发时可能有多个客户端请求Servlet,Servlet必须是线程安全的。
15. 远程方法调用。