0
私はマルチスレッドApache Tomcatサーブレットを作成しようとしています。このサーブレットは処理する各POST本体に大量のテキストを受け取り、GETリクエストを受け取ると受信した一意の単語の数。 QtとQtWebAppライブラリを使ってこれを達成することができましたが、これをJavaで実現することはできません。私はその問題が何であるか正確には分かっていませんが、おそらくアプリケーションの全体的なスレッドセーフティ(または単語がどのように分割され保存されているか)に関係しています。返される単語の数は常に高すぎます(実際の金額よりも2000〜4000倍高く、70000〜140000です。これらのテストケースの結果があります)。私のコードは以下の通りです:apache tomcatサーブレット内のjava HashSetのスレッドセーフ
@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
私はinverseを期待しています。あなたのメソッドは、単語の数よりも少ない文字数を返します。その間にスペースを入れずに行を追加して、すべての行末の単語を次の行の最初の単語に連結します。メモリ内に巨大な文字列を作成し、その巨大な行を分割するのではなく、各行を分割するのはなぜですか?その多くの言葉で、私の推測はあなたが単に正確に数えられなかったということです。小さなサンプルを使用して、コードが期待どおりに機能することをテストしてください(スレッドセーフにした後) –
ありがとうございます。 GETメソッドは、テストケースの最後に1回だけ受信されます。あなたが正しい間に、スレッドが安全でないことが原因でエラーが発生した場合、戻り値はそれ以上ではなくなります。 – user129186