當前位置:編程學習大全網 - 編程語言 - 如何保證集合是線程安全的?

如何保證集合是線程安全的?

並發(concurrency)壹個並不陌生的詞,簡單來說,就是cpu在同壹時刻執行多個任務。

而Java並發則由多線程實現的。

在jvm的世界裏,線程就像不相幹的平行空間,串行在虛擬機中。(當然這是比較籠統的說法,線程之間是可以交互的,他們也不壹定是串行。)

多線程的存在就是壓榨cpu,提高程序性能,還能減少壹定的設計復雜度(用現實的時間思維設計程序)。

這麽說來似乎線程就是傳說中的銀彈了,可事實告訴我們真正的銀彈並不存在。

多線程會引出很多難以避免的問題, 如死鎖,臟數據,線程管理的額外開銷,等等。更大大增加了程序設計的復雜度。

但他的優點依舊不可替代。

死鎖和臟數據就是典型的線程安全問題。

簡單來說,線程安全就是: 在多線程環境中,能永遠保證程序的正確性。

只有存在***享數據時才需要考慮線程安全問題。

java內存區域:

其中, 方法區和堆就是主要的線程***享區域。那麽就是說***享對象只可能是類的屬性域或靜態域。

了解了線程安全問題的壹些基本概念後, 我們就來說說如何解決線程安全問題。我們來從壹個簡單的servlet示例來分析:public class ReqCounterServlet extends HttpServlet{ private int count = 0;

public void doGet(HttpServletRequest request,

HttpServletResponse response) throws IOException, ServletException {

count++;

System.out.print("當前已達到的請求數為" + count);

}

public void doPost(HttpServletRequest request,

HttpServletResponse response) throws IOException, ServletException { // ignore }

}1. 了解業務場景的線程模型

這裏的線程模型指的是: 在該業務場景下, 可能出現的線程調用實況。

眾所周知,Servlet是被設計為單實例,在請求進入tomcat後,由Connector建立連接,再講請求分發給內部線程池中的Processor,

此時Servlet就處於壹個多線程環境。即如果存在幾個請求同時訪問某個servlet,就可能會有幾個線程同時訪問該servlet對象。如圖:

線程模型,如果簡單的話,就在腦海模擬壹下就好了,復雜的話就可以用紙筆或其他工具畫出來。

2. 找出***享對象

這裏的***享對象就很明顯就是ReqCounterServlet。

3. 分析***享對象的不變性條件

不變性條件,這個名詞是在契約式編程的概念中的。不變性條件保證類的狀態在任何功能被執行後都保持在壹個可接受的狀態。

這裏可以引申出, 不可變對象是線程安全的。(因為不可變對象就沒有不變性條件)

不變性條件則主要由對可變狀態的修改與訪問構成。

這裏的servlet很簡單, 不變性條件大致可以歸納為: 每次請求進入時count計數必須加壹,且計數必須正確。

在復雜的業務中, 類的不變性條件往往很難考慮周全。設計的世界是險惡的,只能小心謹慎,用測量去證明,最大程度地減少錯誤出現的幾率。

4. 用特定的策略解決線程安全問題。

如何解決的確是該流程的重點。目前分三種方式解決:

第壹種,修改線程模型。即不在線程之間***享該狀態變量。壹般這個改動比較大,需要量力而行。

第二種,將對象變為不可變對象。有時候實現不了。

第三種,就比較通用了,在訪問狀態變量時使用同步。 synchronized和Lock都可以實現同步。簡單點說,就是在妳修改或訪問可變狀態時加鎖,獨占對象,讓其他線程進不來。

這也算是壹種線程隔離的辦法。(這種方式也有不少缺點,比如說死鎖,性能問題等等)

其實有壹種更好的辦法,就是設計線程安全類。《代碼大全》就有提過,問題解決得越早,花費的代價就越小。

是的,在設計時,就考慮線程安全問題會容易的多。

首先考慮該類是否會存在於多線程環境。如果不是,則不考慮線程安全。

然後考慮該類是否能設計為不可變對象,或者事實不可變對象。如果是,則不考慮線程安全

最後,根據流程來設計線程安全類。

設計線程安全類流程:

1、找出構成對象狀態的所有變量。

2、找出約束狀態變量的不變性條件。

3、建立對象狀態的並發訪問管理策略。

有兩種常用的並發訪問管理策略:

1、java監視器模式。 壹直使用某壹對象的鎖來保護某狀態。

2、線程安全委托。  將類的線程安全性委托給某個或多個線程安全的狀態變量。(註意多個時,這些變量必須是彼此獨立,且不存在相關聯的不變性條件。)

  • 上一篇:如何利用VFW在Delphi中開發視頻捕獲程序
  • 下一篇:軟件工程考研方向
  • copyright 2024編程學習大全網