Java併發編程(Java Concurrency)(2)- 多線程的好處

原文鏈接:http://tutorials.jenkov.com/java-concurrency/benefits.html

  摘要:這是翻譯自一個大概30個小節的關於Java併發編程的入門級教程,原作者Jakob Jenkov,譯者Zhenning Lang,轉載請註明出處,thanks and have a good time here~~~(希望自己不要留坑)

第二節 多線程的好處

儘管多線程編程充滿調整,但其仍被使用的原因是多線程可以帶來很多好處,其中的一些如下:

  • 更有效的資源利用
  • 一些情況下程序設計將變得更加簡單
  • 使程序具有更好的響應性

更有效的資源利用

考慮一個應用程序從本地文件系統讀取並處理文件。假設從磁盤讀取文件需要5秒,而處理文件需要2秒,那麼處理兩個文件花費

1.讀文件A(花費5秒)
2.處理文件A(花費2秒)
3.讀文件B(花費5秒)
4.處理文件B(花費2秒)
總共花費14秒

當從磁盤上讀取文件時,CPU花費了大部分的時間等待磁盤的數據讀取。這期間CPU具有大量的空閒,可以被用來作其他工作。如果將以上操作的順序進行調換,CPU可以得到更充分的使用,具體如下:

1.讀文件A(花費5秒)
2.讀文件B(花費5秒)+處理文件A(花費2秒)
3.處理文件B(花費2秒)
總共花費12秒

CPU首先等待文件A的讀取;隨後立刻讀取文件B,而在文件B的讀取過程中,CPU同時處理文件A。(當然其前提是當從磁盤上讀取文件時CPU大多是時間是空閒的)

通常而言,CPU在等待I/O的過程中可以用來做其他的事情。這裏的I/O不一定是磁盤的I/O,也可能是網絡I/O,或者用戶的輸入。網絡和磁盤I/O通常要慢於CPU和內存的I/O。

使程序設計將變得更加簡單

如果你要利用單線程編寫上述同時讀取和處理文件的例子,你必須處理好每個文件的讀取和處理的狀態。但是如果你用兩個線程分別讀取和處理單個的文件,每個線程在等待從磁盤讀取文件時都會被阻塞,在這個等待的過程中,其他的線程就可以充分地利用CPU來處理他們已經讀取了的文件。這樣一來,磁盤一直在運作,將不同的文件讀入內存,這將同時提高磁盤和CPU的利用率。同時這個例子中程序也更加容易編寫,因爲每個線程僅僅處理單個的文件而不需要考慮全局。

使程序具有更好的響應性

多線程的另一個好處是使得程序具有更好的響應性。假設一個服務器程序正在監聽一些端口的請求消息,當一個請求到達時,程序就處理這個請求然後繼續其監聽。服務器程序的流程如下:

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

如果處理一個請求的時間過長,這期間其他的來自客戶端的請求將無法被服務器捕獲。只有當服務器監聽時請求才能得到響應。

另一種設計是讓監聽線程將監聽到的請求傳遞給處理線程,然後立即繼續監聽。處理線程處理請求並向客戶端發送回覆。其流程如下:

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

這樣一來服務器始終處於監聽中,不存在無法被捕獲的請求,服務器的響應能力得到了提升。

這個好處對於桌面應用程序來說同樣適用。如果你點擊一個按鈕,這個按鈕啓動了一個長時間的任務,而執行這個任務的線程就是更新窗口和按鈕等控件的線程,那麼當這個任務被執行時,程序將失去響應。另一種程序結構是,這個任務可以被傳給一個處理線程來進行處理。這樣當處理線程處理這個任務的時候,窗口依舊可以響應其他的用戶操作。當處理線程運行結束後,他將給窗口線程發送消息。窗口線程根據任務的處理的結果來更新應用的窗口顯示。可以看出,具有單獨的任務處理線程的設計對於用戶來說具有更好的響應性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章