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源碼。
您的「GET」方法處理使用該集合,但不會獲取該鎖。這可能是一個問題。除非特別記錄它們,否則內置的Java集合都不是線程安全的。 – dsh
我期待反過來:你的方法應該返回少於單詞的數量,因爲你在它們之間插入一行而不插入空格,從而將所有的行尾單詞與下一行的第一個單詞連接起來。你爲什麼不分割每一行,而不是在內存中創建一個巨大的字符串,然後分割這條巨大的線?用這麼多的話,我的猜測是,你根本沒有正確計數。只需使用一個小樣本來測試代碼是否按預期工作(在使其線程安全後) –
感謝您的輸入。 GET方法只在測試用例結束時被接收一次。雖然你是正確的,但由於線程不安全而導致的任何錯誤都會導致返回值更少,而不是更多。 – user129186