JAVA線程安全及性能的優化筆記(六)——Web服務器開發環境下的線程安全問題

本文轉載自:JAVA線程安全及性能的優化筆記(六)——Web服務器開發環境下的線程安全問題


Servlet是在多線程環境下的。即可能有多個請求發給一個servelt實例,每個請求是一個線程。

struts下的action也 類似,同樣在多線程環境下。可以參考struts user guide: http://struts.apache.org/struts-action/userGuide /building_controller.html 中的Action Class Design Guidelines一節: Write code for a multi-threaded environment - Our controller servlet creates only one instance of your Action class, and uses this one instance to service all requests. Thus, you need to write thread-safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets.

譯:爲多線程環境編寫代碼。我們的controller servlet指揮創建你的Action 類的一個實例,用此實例來服務所有的請求。因此,你必須編寫線程安全的Action類。遵循與寫線程安全的servlet同樣的方針。

1. 什麼是線程安全的代碼

在多線程環境下能正確執行的代碼就是線程安全的。

安全的意思是能正確執行,否則後果是程序執行錯誤,可能出現各種異常情況。

2. 如何編寫線程安全的代碼

很多書籍裏都詳細講解了如何這方面的問題,他們主要講解的是如何同步線程對共享資源的使用的問題。主要是對synchronized關鍵字的各種用法,以及鎖的概念。

Java1.5中也提供瞭如讀寫鎖這類的工具類。這些都需要較高的技巧,而且相對難於調試。

但是,線程同步是不得以的方法,是比較複雜的,而且會帶來性能的損失。等效的代碼中,不需要同步在編寫容易度和性能上會更好些。

我這裏強調的是什麼代碼是始終爲線程安全的、是不需要同步的。如下:

  1. 常量始終是線程安全的,因爲只存在讀操作。
  2. 對構造器的訪問(new 操作)是線程安全的,因爲每次都新建一個實例,不會訪問共享的資源。
  3. 最重要的是:局部變量是線程安全的。因爲每執行一個方法,都會在獨立的空間創建局部變量,它不是共享的資源。局部變量包括方法的參數變量。

struts user guide裏有:

Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.

譯:只使用用局部變量。–編寫線程安全的代碼最重要的原則就是,在Action類中只使用局部變量,不使用實例變量。

總結

在Java的Web服務器環境下開發,要注意線程安全的問題。最簡單的實現方式就是在Servlet和Struts Action裏不要使用類變量、實例變量,但可以使用類常量和實例常量。

如果有這些變量,可以將它們轉換爲方法的參數傳入,以消除它們。

注意一個容易混淆的地方:被Servlet或Action調用的類中(如值對象、領域模型類)中是否可以安全的使用實例變量?如果你在每次方法調用時

新建一個對象,再調用它們的方法,則不存在同步問題—因爲它們不是多個線程共享的資源,只有共享的資源才需要同步—而Servlet和Action的實例對於多個線程是共享的。

換句話說,Servlet和Action的實例會被多個線程同時調用,而過了這一層,如果在你自己的代碼中沒有另外啓動線程,且每次調用後續業務對象時都是先新建一個實例再調用,則都是線程安全的。


本文轉載自:JAVA線程安全及性能的優化筆記(六)——Web服務器開發環境下的線程安全問題

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