Multithreading Benefits [多线程带来的福利]

Descriptions:
java 并发文档翻译,文章链接地址http://tutorials.jenkov.com/java-concurrency/benefits.html


The reason multithreading is still used in spite of its challenges is that multithreading can have several benifits.
虽然使用多线程编程有着诸多挑战,但是它却仍被广泛使用的原因是因为多线程本身具有着许多优势。

Some of these benefits are:
优势如下:

  • Better resource utilization.
  • (多线程)对资源的利用率更高。

  • Simpler program design in some situations.

  • 在某些特定场合可以简化程序的设计。

  • More responsive programs.

  • 可以写出响应性更好的程序。

Better resource utilization

更好的资源利用率

Imagine an applicaton that reads and processes files from the local file system.
设想一下有从本地文件系统读入并执行文件这样一段程序。

Lets say that reading a file from disk takes 5 seconds and processing it takes 2 seconds. Processing two files then takes
假设如果从磁盘上面将文件加载到当前程序中需要 5s ,然后执行该文件需要 2s.
那么代码处理 2 份文件的所需要的时间统计如下所示:


  5 seconds reading file A
  2 seconds processing file A
  5 seconds reading file B
  2 seconds processing file B
  ************************
  14 seconds total

When reading the file from disk most of the CPU time is spent waiting for the disk to read the data.
当程序在执行从磁盘上读入文件的这段期间内 CPU 将大部分的时间花费在等待上。

The CPU is pretty much idle druing that time.
在等待的那段期间内,CPU 很有可能处于一种空闲状态。

It could be doing something else.
而在那段时间内 CPU 完全是可以做点其他的事情的。

By changing the order of the operations, the CPU could be better utilized. Look at this ordering:
通过修改执行操作的顺序,能够提升 CPU 的利用率。
可以参照如下的顺序:


  5 seconds reading file A
  5 seconds reading file B + 2 seconds processing file A
  2 seconds processing file B
  ********************
  12 seconds total

The CPU waits for the first file to be read.
CPU 在首次从磁盘读入文件的时候处于等待状态。

Then it starts the read of the second file.
然后,开始第二份文件的加载操作。

While the second file is being read, the CPU processes the first file.
当等待第二份文件从硬盘加载的期间内, CPU 会运行程序来处理读入第一份文件。

Remember, while waiting for the file to be read from disk, the CPU is mostly idel.
记住这一点,当 CPU 处于等待文件从磁盘加载文件的这段期间时, CPU 十有八九是处于空闲状态的。

In general, the CPU can be doing other things while waiting for IO.
就通常情况来说,当 CPU 等待 IO 操作的这段期间内完全可以做一些其他事情。

It doesn’t have to be disk IO.
也不一定非要是基于磁盘的 IO 操作。

It can be network IO as well, or input from a user at the machine.
还可以是基于网络的 IO 操作,或是来自于另外一台主机用户的输入数据。

Network and disk IO is often a lot slower than CPU’s and memory IO.
网络和磁盘上数据的读入写出速度通常要远远比 CPU 直接读写内存的速度要慢。

Simpler program desgin in some situations

在特定场合更简洁的程序设计

If you were to program the above ordering of reading and processing by hand in a singlethread applicaton, you would have to keep track of both the read and procesisng state of each file.
如果你曾试图将上述的代码按照读、执行的顺序来用单线程编写实现的话,你将不得不在每个线程中保存为每个文件的读取和执行的相关状态信息。

Instead you can start two threads that each just reads and processes a single file.
同样你也可以创建两个线程,让每个线程仅做读文件或是处理文件中的一种。

Each of these threads will be blocked while waiting for the disk to read its file.
每当线程等待从文件从磁盘中读取的时间段内都会陷入阻塞状态。

While waiting, other threads can use the CPU to process the parts of the file they have already read.
在该线程处于等待的过程中,其他的线程便会使用 CPU 资源来操作它已经从磁盘加载到内存的文件。

The result is, that the disk is kept busy at all times, reading from various files into memory. This results in a better utilization of both the disk and the CPU.
这样操作的结果便是可以保证磁盘一直处于忙碌状态,将不同的文件加载到内存中。 这种处理方法也可以提高使磁盘和 CPU 的资源利用率。

It is also easier to program, since each thread only has to keep track of a single file.
另一个好处便是是程序的代码编写起来更加的容易,因为每个线程仅仅需要保存单个文件的信息即可。

More responsive programs

写出响应性更好的程序

Another common goal for turning a singlethreaded application into a multithreaded application is to achieve a more responsive application.
将单线程应用程序改写成多线程应用程序的另一个目的便是获得应用程序更好的响应能力。

Imagine a server application that listens on some port for incoming requests, when a request is received, it handles the request and then goes back to listening.
假设在某个端口上监听是否有请求到来的服务器应用程序, 如果接到了一个请求的话,这个服务器应用程序首先会处理这个请求,然后等到处理请求之后才会返回去继续监听操作。

The server loop is sketched below.
关于上述服务器的程序概况描述如下.


while (server is active){
    listen for request
    process request
}

If the request takes a long time to process, no new client can send requests to the server for that duration.
如果服务器端执行的请求需要很长的一端时间,那么在那段时间内没有任何客户端能够成功的将自己的请求发送至服务器端。

An alternate design would be for the listening thread to pass the request to a worker thread, and return to listening immediately.
可以在设计上进行这样的变动: 创建一个用来将请求信息转发给处理请求的工作者线程这样的请求转发线程,每当转发执行结束便会立即恢复到监听的状态。

The worker thread will process the request and send a reply to the client.
而上述设计变动中所描述的工作者线程将会执行具体的请求,然后将执行结果回复给客户端。

This design is sketched below:
上述的设计概况可以描述如下:


while ( server is active){
    listen for request
    hand request to worker thread
}

This way the server thread will be back at listening sooner.
在这种设计模式下,服务器线程能够在响应请求连接之后很短的时间内回复到监听状态。

Thus more clients can send requests to the server.
因此能够满足让更多的客户端将请求发送给服务器端。

The server has become more responsive.
这样的服务器的响应性更好。

The same is true for desktop applications.
上述的道理对于桌面应用程序来说也说得通。

If you click a button that starts a long task, and the thread executing the task is the thread updating the windows, button etc., then the application will appear unresponsive while the task executes.
如果你通过点击一个按钮来启动一个长任务的话,并且该线程所执行任务是更新 windows 系统,不过在更新任务执行的时间段内该程序对于所有的操作都不会有任何响应操作。

Instead the task can be handed off to a worker thread.
如果我们将’更新’任务交给一个工作者线程来完成的话。

While the worker thread is busy with the task, the window thread is free to respond to other user requests.
那么即便是工作者线程处于繁忙的执行任务状态,窗口线程仍是处于空闲状态且能够立即响应来自其他用户的请求。

When the worker thread is done it signals the window thread.
当工作者线程完成了它的工作的话,它便会向窗口线程发送信号。

The window thread can then update the application windows with the result of the task.
(接收到信号的)窗口线程随后便可以根据工作线程执行的结果来更新窗口应用程序。

The program with the worker thread design will appear more responsive to the user.
如果在设计程序的时候为其增设工作者线程的话将会让程序对于用户而言更具有响应性。

下一篇文章

end