尽管面临很多挑战,多线程还是有一些优点使得它被一直使用。如下:
- 资源利用更好
- 程序设计在某些情况下更简单
- 程序响应更快
资源利用更好
想象一下,一个应用程序需要从本地文件系统中读取和处理文件的情景。比方说,从磁盘读取一个文件需要 5 秒,处理一个文件需要 2 秒。处理两个文件则需要
5 秒读取文件 A
2 秒处理文件 A
5 秒读取文件 B
2 秒处理文件 B
---------------
总共需要 14 秒
从磁盘中读取文件的时候,大部分的 CPU 时间用于等待读取数据。这段时间里,CPU 非常空闲。它可以做一些事情,通过改变操作顺序,就能够更好的使用 CPU 资源。看下面的顺序:
5 秒读取文件 A
5 秒读取文件 B + 2 秒处理文件 A
2 秒处理文件 B
---------------
总共需要 12 秒
CPU 等待第一个文件被读取完,然后开始读取第二个文件。当第二个文件再被读取的时候,CPU 会去处理第一个文件。记住,在等待磁盘读取文件的时候,CPU 大部分时间是空闲的。
总的来说,CPU 能够在等待 IO 的时候做一些事情。这个不一定就是磁盘 IO,也可以是网络 IO,或者用户输入。通常情况下网络和磁盘 IO 比 CUP 和内存 IO 慢的多。
程序设计更简单
在单线程应用程序中,如果想实现程序手动处理上面所提到的读取和处理顺序,你必须记录每个文件读取和处理状态。相反,你可以启动两个线程,每个线程处理一个文件的读取和处理操作。线程会在等待磁盘读取文件过程中阻塞。在等待的时候,其他线程能够使用 CPU 去处理已经读取完的文件。其结果就是,磁盘总是在繁忙的读取不同文件到内存中。这会带来磁盘和 CPU 利用率的提升。而且每个线程只需要记录一个文件,因此这种方式更加容易实现。
程序响应更快
将一个单线程应用程序变成多线程应用程序的另一个常见的目的是实现一个响应更快的应用程序。设想一个服务器应用,它在某一个端口监听进来的请求。当一个请求到来时候,它去处理这个请求,然后返回监听。
while(server is active){
listen for request
process request
}
如果一个请求占用大量的时间来处理,在这段时间内新的客户端就无法发送请求给服务器。只有服务器在监听的时候,请求才能被接受。另一种设计是,监听线程,把请求传递给工作线程(worker thread),然后立刻返回监听。而工作线程则能够处理这个请求并发送一个回复给客户端。如下所示。
while(service is active){
listen for request
hand request to worker thread
}
这种方式,服务端线程迅速返回去监听,因此,更多的客户端能够发送请求给服务器,这个服务也变得更快。
1693

被折叠的 条评论
为什么被折叠?



