私はJavaSEのバックグラウンドを持っており、サーブレットのチュートリアルをいくつか行い、Head First JSP&サーブレットを読みました。非同期サポートに関するJavaWorld.comの記事を読んでいますが、よくわかりません。
Asyncとは何ですか?Ajaxとサーブレット非同期の違いは何ですか?
PS私はajaxでPHPのバックグラウンドを持っていて、その概念を知っていますが、Javaで試したことはありません
私はJavaSEのバックグラウンドを持っており、サーブレットのチュートリアルをいくつか行い、Head First JSP&サーブレットを読みました。非同期サポートに関するJavaWorld.comの記事を読んでいますが、よくわかりません。
Asyncとは何ですか?Ajaxとサーブレット非同期の違いは何ですか?
PS私はajaxでPHPのバックグラウンドを持っていて、その概念を知っていますが、Javaで試したことはありません
従来のサーブレット モデルでは、1 リクエストが 1 スレッドに対応するのが通常でした。
これらのスレッドは通常、サーブレット コンテナーによって管理されるプールから取得されます。サーブレット コンテナは、このプールに空きスレッドがある限り、新しいリクエストのみを処理できます。独自のコードがリクエストの処理でビジーである限り、スレッドは解放されません。
状況によっては、このモデルを破る価値があるかもしれません。このようなサーブレット コンテナー管理スレッドを介してサーブレットにリクエストが到着すると、コードは非同期実行を要求します。その後、サーブレット リクエストから戻ることができ、コンテナ スレッドが解放されます。
同期リクエスト処理とは対照的に、これはレスポンスをコミットせず、接続を閉じません。代わりに、非同期コンテキストを別のスレッド プールに渡すことができます。別のスレッド プールはそれを取得できます。一部のスレッドがそれを処理できるようになったら、それを処理して、応答に書き込むことができます。
例:
@WebServlet(urlPatterns = "/somepath", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
@EJB
private AsyncBean asyncBean;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
// The following line will not block and return immediately
asyncBean.doAsyncStuff(asyncContext);
} // Shortly after this method has ended, thread will be returned to pool
}
次のAsyncBean
ように実装されています。
@Stateless
public class AsyncBean {
@Asynchronous
public void doAsyncStuff(AsyncContext asyncContext) throws IOException {
asyncContext.getResponse().getWriter().write("test");
}
}
上記のコードでは、メソッドから戻った直後のどこかAsyncServlet#doGet()
で、サーブレット スレッドがプールに返されます。実行するための「リクエスト」(タスク) はAsyncBean#doAsyncStuff()
、EJB スレッド プールがピックアップするためにキューに入れられます。
これを使用する理由と時期に対する答えは、それほど単純ではありません。スレッドを保持したいだけの場合、上記のケースでは、あるスレッド プールのスレッドを別のスレッド プールと交換することになり (この場合はサーブレット プールと EJB 非同期プール)、純利益はそれほど多くありません。サーブレット スレッド プールに追加のスレッドを与えることもできます。
ただし、より高度なシナリオでは、リクエストをよりきめ細かく管理できます。それらを複数のタスクに分割し、それらのタスクにスレッド プール サービスを提供します。たとえば、10 MB のファイルに対する 100 のダウンロード リクエストが、ラウンド ロビンが各リクエストに一度に 100 KB を送信する 10 のスレッドによって処理されると想像してください。
さらに別のアプリケーションは、外部システムからのデータを待機する必要がある要求であり、この外部システムは、要求元に中継できるメッセージを送信できます。つまり、とにかく応答を待つ別のスレッドが必要になるため、データベース呼び出しはここでは意味がありません。次に、あるスレッドを別のスレッドに再度変更します。しかし、受信メールなどを待つ必要がある場合は、1 つのスレッドで任意のメールを待機し、それを保留中のリクエストに中継できます。