2012-04-08 15 views
32

私はJava SEのバックグラウンドから来ており、いくつかのサーブレットのチュートリアルを行い、Head First JSP &サーブレットを読んでいます。私は今非同期サポートについてのJavaWorld.comの記事を読んでいますが、私はそれをよく理解していません。サーブレット3.0 APIの非同期サポート

Asyncは単純に何ですか? AjaxとServlet Asyncの違いは何ですか?私はAJAXとPHPの背景を持っていると私は考え方を知っているが、私は、伝統的なサーブレットモデルでJava

答えて

81

でそれを試していない

P.Sは、それが1つの要求は1つのスレッドに対応していることを通常の場合です。

これらのスレッドは、通常、サーブレットコンテナによって管理されるプールに由来します。サーブレットコンテナは、このプールに空きスレッドがある限り、新しい要求のみを処理できます。独自のコードが要求の処理に忙しい限り、スレッドは空き状態ではありません。

場合によっては、このモデルを破る価値があります。何が起こるかは、そのようなサーブレットコンテナ管理スレッドを介してリクエストがサーブレットに到着し、コードが非同期実行を要求することです。サーブレットの要求から戻ると、コンテナスレッドは解放されます。

同期要求処理とは異なり、これは応答をコミットしないため、接続を閉じることはありません。代わりに、非同期コンテキストを別のスレッドプールに渡すことができます。別のスレッドプールは、それを取り上げることができます。また、スレッドが処理できないスレッドがある場合は、そのスレッドプールに応答して応答に書き込むことができます。

例:あなたはAsyncServlet#doGet()メソッドから返さどこか直後に、サーブレットスレッドがに返される、上記のコードで

@Stateless 
public class AsyncBean { 

    @Asynchronous 
    public void doAsyncStuff(AsyncContext asyncContext) throws IOException { 
     asyncContext.getResponse().getWriter().write("test"); 
    } 
} 

:として実装されているAsyncBean

@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#doAsyncStuff()を実行するための「要求」(タスク)は、EJBスレッドプールが拾うためにキューに入れられます。

これを使用するWHYとWHENの答えはそれほど簡単ではありません。スレッドを保存するだけの場合は、上記の場合、スレッドプールをもう一方のスレッドプール(この場合はサーブレットプールとEJB非同期プール)から交換して、純利益はそれほど大きくはありません。サーブレットスレッドプールに余分なスレッドを与えているだけでも可能です。

さらに高度なシナリオでは、より細かい要求の管理が可能です。それらを複数のタスクに分割し、これらのタスクにスレッドプールサービスを提供します。例えば。 10スレッドで処理される10MBのファイルに対して100回のダウンロード要求があると想像してください。ラウンドロビンによって各要求に100KBの時間が送信されます。

さらに別のアプリケーションは、外部システムからのデータを待つ必要がある要求であり、この外部システムはリクエスタにリレーできるメッセージを送信できる場所です。私。とにかく応答を待っている別のスレッドが必要になるため、データベース呼び出しはここでは意味をなさないでしょう。次に、別のスレッドを別のスレッドに変更します。しかし、あなたが着信電子メールを待つ必要がある場合、1つのスレッドは電子メールを待って、中断した要求にそのスレッドを中継することができます。

+2

ありがとうたくさんのArjan、最初の段落は本当に明確で分かりやすいです。 –

+4

1つのプールから別のプールへのスレッドの移動が、スケーラビリティの観点からどのように異なるのかを十分に理解していません。私は、サーバーリスナースレッドをプールに戻す際のポイントを見ていますが、アプリケーションのスケーラビリティを大幅に向上できるかどうかはわかりません。 –

+3

スレッドの交換はスケーラビリティには役立ちませんが、ダウンロードの例を参照してください。いくつかのスレッドは、多くの非同期接続にフィードを提供することができます。要求をキューに入れられるなどのいくつかのタスクに分割することができれば、このモードを検討する価値があります。そうでなければ、実際には期待されるメリットはあまりありません。 –

関連する問題