1

ねえ、私はすべてのシングルユーザーに対して一度だけスレッドを開始するJavaサーブレットを実装したいと思います。更新しても、再開しないでください。私の最後のアプローチは私にいくつかの問題をもたらしたので、コードはありません^^。サーブレットのレイアウトに関する提案はありますか?

 public class LoaderServlet extends HttpServlet {
// The thread to load the needed information
private LoaderThread loader;
// The last.fm account
private String lfmaccount;

public LoaderServlet() {
    super();
    lfmaccount = "";
}

@Override
protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    if (loader != null) {
        response.setContentType("text/plain");
        response.setHeader("Cache-Control", "no-cache");
        PrintWriter out = response.getWriter();
        out.write(loader.getStatus());
        out.flush();
        out.close();
    } else {
        loader = new LoaderThread(lfmaccount);
        loader.start();
        request.getRequestDispatcher("WEB-INF/pages/loader.jsp").forward(
                request, response);
    }
}

@Override
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    if (lfmaccount.isEmpty()) {
        lfmaccount = request.getSession().getAttribute("lfmUser")
                .toString();
    }
    request.getRequestDispatcher("WEB-INF/pages/loader.jsp").forward(
            request, response);
}
}

jspはajaxを使用して定期的にサーブレットに投稿し、ステータスを取得します。スレッドはちょうど3分のように実行され、last.fmデータをクロールします。

4

5 に答える 5

1

javax.servlet.SingleThreadModel を実装 => サービスメソッドは同時に実行されません。サーブレットの仕様を参照してください。

于 2012-10-17T10:59:08.643 に答える
1

ここで必要なのはSession listenerです。このメソッドsessionCreated()は、ブラウザー セッションごとに 1 回だけ呼び出されます。そのため、ユーザーがページを更新しても問題はありません。sessionCreated()その後、メソッド呼び出しごとにスレッドを開始できます。

于 2012-10-17T10:51:45.447 に答える
0

私が理解しているように、同じユーザーからのリクエストの並列処理を避けたいと考えています。他のアプローチをお勧めします。各ユーザーにロックを関連付けて、セッションに保存します。そして、ユーザーリクエストの処理を開始する前に、そのロックを取得してみてください。したがって、現在のスレッドは、このユーザーからの他の要求が処理されている間待機します。(セッションの作成時に、セッションリスナーを使用してロックを保存します)

于 2012-10-17T10:50:36.153 に答える
0

最初のタスクは、ユーザーを一意に識別する方法を理解することです。たとえば、プロキシ/SOHO ゲートウェイの背後にあるさまざまなユーザーをどのように識別しますか?

それを理解したら、基本的には、ユーザー <-> スレッドをサーブレットにマップするシングルトン オブジェクトを作成するだけです。

そして、@ beny23が上記のコメントで言及しているように、スケーラビリティの問題に入ります...私はその指摘に完全に同意します-あなたのアプローチはスケーラビリティに関して健全ではありません!

乾杯、

于 2012-10-17T10:49:12.437 に答える
0

仮説的には、 を作成することで実装できMap<String,Thread>、サーブレットが呼び出され、 でマップを検索しようとしますsessionId

ただのスケッチ:

public class LoaderServlet extends HttpServlet {

  private Map<String,Thread> threadMap = new HashMap<>();

  protected void doPost(..) {
    String sessionId = request.getSesion().getId();
    Thread u = null;
    if(threadMap.containsKey()) {
        u = threadMap.get(sessionId);
    } else {
       u = new Thread(...);
       threadMap.put(sessionId, u);
    }
    // use thread 'u' as you wish
  } 

}

ノート:

  • これは、ユーザーではなくセッションIDを使用してスレッドを関連付けます
  • 見てくださいThreadPools、彼らは素晴らしいです
  • コメンターが指摘したように:このスケッチでは同期の問題は考慮されていません
于 2012-10-17T10:52:41.280 に答える