2011-11-18 36 views
0

servlet類處理傳入的請求對象,將數據存儲到StringBuilder/StringBuffer中,並將數據傳遞到另一個類以寫入文件。我真的應該關心servlet中的線程安全問題操作類

ActionClass 
    public void doPost(HttpServletRequest request,HttpServletResponse response) 
    throws ServletException,IOException { 
     String fileName = request.getparameter("fileName"); 
     String body = request.getParameter("innerHTML"); 
     String head = request.getParameter("headContents"); 

     StringBuilder sbr = new StringBuilder(); 
     sbr.append(body); sbr.append(head); 
         OR 
     StringBuffer sbf = new StringBuffer(); 
     sbf.append(body); sbf.append(head); 

    FileWrite fw = new FileWrite(fileName, sbf/sbr); /* write the data into file*/ 
      } 

FILEWRITE

class FileWrite{ 
     public FileWrite(String fileName, StringBuilder sbf){ 
     boolean isExist = checkFileName(fileName); /* return true or false */ 
     if(isExist){ 
      String name = reName(fileName); /* rename & return new name */ 
       /* write the file in new file */ 
      }else{ /* write in same file name */ } 
     } 

    public String reName(String oldName){ 
      /* rename oldName as newName & checks via isExist(newName) */ 
      } 

    public boolean isExist(String filename) { 
     // checks the file in directory, if found already 
     return true; 
      else return false; 
     } 
    } 

,你可以看到在上面的例子,操作類的數據傳送到FileWrite class其將數據寫入一個新文件。有數百個客戶端可能同時發送請求將數據存儲在新文件中。
所以我的問題是,在servlet類中應該用什麼來存儲數據。是不是String or stringBuffer or StringBuilder ??是線程安全的問題嗎?

+0

我會建議你展示你的代碼是什麼方法,以便我們不必做出假設(根據尼爾關於doGet或doPost的評論) – Nathan

+0

@Nathan:我已修改並編寫了其他類和方法。我不確定'FileWrite類或它的方法'是否需要線程安全,但我希望你現在可以明白我的觀點。再次感謝 – user1010399

回答

3

是的,你應該關心線程安全問題,但線程安全問題不在你選擇的字符串或stringBuffer或StringBuilder中。

如果您需要注意(潛在地)線程安全性,是否您的FileWriter類獲得了兩個相同文件名的請求。

另外,我會注意到,從安全角度來看,直接從get參數直接獲取原始文件位置是非常危險的 - 因爲用戶可以覆蓋其他用戶文件或(可能取決於權限)甚至OS文件。

+0

非常輝煌的答案。是的文件名可能會被覆蓋,但我有另一個應用程序檢查現有的文件名,如果文件名是相同的,那麼它重命名文件並通知客戶端。 – user1010399

+0

Nathan,正如你所說的那樣,我嚴格地感覺到'FileWriter類'中必定存在線程安全問題,因此確保線程安全的正確方法是什麼。 '靜態同步方法()或同步方法' – user1010399

2

只要它發生在你的servlet的doGet或doPost中,那麼你只能處理一個線程。因此,不需要線程安全,這意味着您應該使用比StringBuffer快的StringBuilder。

+0

我認爲你的意思是「不需要線程安全」而不是「不需要類型安全」 – Nathan

+0

偉大的,同樣的事情我在想什麼,但我沒有那麼自信,也無法在谷歌上找到答案。多謝。 – user1010399

+0

謝謝你,你們倆都是對的。我的意思是線程。 –

0

來自Java文檔。

StringBuilder的實例對於多線程使用並不安全。如果需要這種同步,那麼建議使用StringBuffer。所有字符串的

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html

首先是內在的。

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#intern()

,如果你有相同的字符串這意味着,這不是一個問題。

如果您的頁眉和頁腳是靜態的,它可能是一個靜態變量。

1

對於每一個新的請求,都會產生一個新的servlet線程,並擁有自己正確包裝的唯一上下文。因此,doPost doGet中的數據被保存在該上下文中,因此可以安全地避免其他請求。

只要String vs StringBuffer vs StringBuilder被考慮,因爲上下文本身是線程安全的,所以沒有同步問題,所以你可以去springbuilder。

附註:如果沒有變化發生,爲什麼不去簡單的字符串?

順便說一下..期待兩個請求來同一個文件!

+0

是的,我只想使用字符串,但線程安全的恐懼迫使我思考StringBuffer與StringBuilder。這就是爲什麼我只是問這個問題。非常感謝Nikunj – user1010399

0

如果你在一個方法中聲明瞭變量,它將被放置在一個只有當前線程可以訪問的地方調用線程棧。所以你不必擔心線程的安全性,只要它是一個局部變量 在你的你應該使用StringBuider,因爲它更快,不需要擔心線程安全

-1

你的編碼器是線程安全的,這在多線程環境中沒有問題。因爲你的ServleClass沒有Class級別或實例級別的變量,所以你的FileWrite是post中的方法的實例。 erver的請求將有一個新的FileWrite ..

相關問題