多線程提高系列(1)--線程的優勢以及風險性

一、線程的優勢

(1)充分發揮多處理器的強大能力:由於線程是CPU調度和分配的基本單位,因此如果在程序中只有一個線程,那麼最多同時在一個處理器上運行。在雙核處理器系統上,單線程的程序只能使用一半的CPU資源,而在擁有100個處理器的系統上,將有99%的資源無法使用。另一方面,多線程程序可以同時在多個處理器上運行。如果設計合理,多線程程序可以通過提高處理器資源的利用率來提升系統吞吐率。
使用多個線程 還有助於在單處理器系統上獲取更高的吞吐率,如果程序是單線程的,那麼當線程等待某個同步IO操作完成時,處理器將處於空閒狀態。而在多線程程序中,如果一個線程在等待IO才做完成時,另一個線程可以繼續運行,使程序能夠在IO阻塞期間繼續運行。

(2)建模的簡單性:當只需要執行一種類型(例如修改12個錯誤)的任務時,在時間管理方面比執行多種類型(修復錯誤、修改幻燈片等)的任務要簡單。當只有一種類型的任務需要完成時,只需做這一件,直到所有的任務完成,不需要進行切換。

(3)異步事件的簡化處理:服務器應用程序在接受來自多個遠程客戶端的套接字連接請求時,如果爲每個連接都分配其各自的線程並且使用同步IO,那麼將會大大降低開發難度。

(4)響應更靈敏的用戶界面:在現代的GUI框架中,例如AWT和Swing等工具中,都採用一個事件分發線程(Event Dispatch Thread,EDT)來替代主事件循環。當某個用戶界面事件發生時,在事件線程中將調用應用程序的事件處理器。由於大多數GUI框架都是單線程子系統,因此到目前爲止仍然存在主事件循環,但它現在處於GUI工具的控制下並在自己的線程中運行,而不是在應用程序的控制下。

二、線程帶來的風險

(1)安全性問題:線程安全性可能是非常安全的,在沒有充足同步的情況下,多個線程中的操作執行順序是不可預測的,甚至會產生奇怪的結果,下面的UnsafeSequence類中將產生一個整數值序列,該序列中的每個值都是唯一的,在這個類中簡要地說明了多個線程之間的交替操作將會如何導致不可預料的結果。在單線程環境中,這個類能正確的工作,但在多線程環境中則不能。

package MultiThreading;

/**
 * Created by L_kanglin on 2017/4/11.
 */
public class UnsafeSequence {
    private int value;
    //返回一個唯一的數值
    public int getNext(){
        return value++;
    }
}

UnsafeSequence的問題在於,如果執行時機不對,那麼兩個線程在調用getNext時會得到相同的值。雖然遞增運算someVarible++看上去是單個操作,但事實上它包含三個獨立的操作:讀取value、將value加1、並將計算結果寫入value。由於運行時可能將多個線程之間的操作交替執行,因此這兩個線程可能同時執行讀操作,從而使它們得到相同的值,並都將這個值加1,結果就是,在不同的線程的調用中返回了相同的數值。

(2)活躍性問題
安全性的含義是“永遠不發生糟糕的事情”,而活躍性則關注於另一個目標,即“某件正確的事情最終會發生”。比如:如果線程A在等待線程B釋放其持有的資源,而線程B永遠都不會釋放該資源,那麼A將一直等待下去。

(3)性能問題
在多線程程序中,當線程調度器臨時掛起活躍線程並轉而運行另一個線程時,就會出現頻繁的出現上下文切換操作,這種操作將帶來極大的開銷:保存和恢復執行上下文,丟失局部性,並且CPU時間將更多的花在線程調度而不是線程運行上。

發佈了104 篇原創文章 · 獲贊 56 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章