2016-04-28 28 views
0

我想寫一個多線程的Apache Tomcat的servlet,它將接收大量的文本在它的每個POST正文處理和GET請求時,它將返回收到的唯一字數。我已經設法使用Qt和QtWebApp庫來實現這一點,但我似乎無法在Java中完成此操作。我不確定問題是什麼,但大概是應用程序的整體線程安全性(或者如何分割和保存單詞)。返回的字數總是太高(大約比實際數量高2000-4000,這是70000到140000--我確實有這些測試結果)。我的代碼如下:線程安全的Java HashSet在Apache的Tomcat servlet

@WebServlet(name = "data", urlPatterns =  {"/myserver/","/myserver/data","/myserver/count"}) 
public class data extends HttpServlet { 

HashSet<String> slova = new HashSet<>(); 
public final Lock lock = new ReentrantLock(); 

protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    response.setContentType("text/html;charset=UTF-8"); 


    try (PrintWriter out = response.getWriter()) { 


     if("POST".equals(request.getMethod()) && "/osp/myserver/data".equals(request.getRequestURI())){ 

     InputStream body = request.getInputStream(); 
     GZIPInputStream gstream = new GZIPInputStream(body); 
     BufferedReader buffreader = new BufferedReader(new InputStreamReader(gstream, "UTF8")); 


     String vse =""; 
     StringBuffer sbuffer = new StringBuffer(); 

     while ((vse = buffreader.readLine()) != null) 
     { 
      sbuffer.append(vse); 
     } 

     String text = sbuffer.toString(); 
     System.out.println(text); 


      String[] words = text.split("\\s+"); 

      lock.lock(); 
      for(int i = 0; i < words.length; i++){ 

       slova.add(words[i]); 

      } 
      lock.unlock(); 

     } 
     if("GET".equals(request.getMethod()) && "/osp/myserver/count".equals(request.getRequestURI())){ 

      out.println(slova.size()); 
      slova.clear(); 
     } 

    } 
} 

任何想法可能導致這種情況?任何反饋將不勝感激。我可以根據要求發佈工作Qt源碼。

+1

您的「GET」方法處理使用該集合,但不會獲取該鎖。這可能是一個問題。除非特別記錄它們,否則內置的Java集合都不是線程安全的。 – dsh

+2

我期待反過來:你的方法應該返回少於單詞的數量,因爲你在它們之間插入一行而不插入空格,從而將所有的行尾單詞與下一行的第一個單詞連接起來。你爲什麼不分割每一行,而不是在內存中創建一個巨大的字符串,然後分割這條巨大的線?用這麼多的話,我的猜測是,你根本沒有正確計數。只需使用一個小樣本來測試代碼是否按預期工作(在使其線程安全後) –

+0

感謝您的輸入。 GET方法只在測試用例結束時被接收一次。雖然你是正確的,但由於線程不安全而導致的任何錯誤都會導致返回值更少,而不是更多。 – user129186

回答

0

JB Nizet提到的字符串拆分是問題的根源。