事前計算が必要なデータが入力にservlet2
依存せず、一度だけ計算する必要がある場合は、 inまたは inservlet1
で熱心に計算します。ただし、計算に時間がかかる場合は、バックグラウンド スレッドに移動して、アプリケーションの起動時間が長くならないようにすることをお勧めします (これらのメソッドは、完了するまで展開をブロックします)。ServletContextListener.contextInitialized()
GenericServlet.init()
簡単な例を次に示します。
public class Servlet2 extends HttpServlet {
private final ExecutorService threadPool = Executors.newSingleThreadExecutor();
private Future<String> calculationResult;
@Override
public void init() throws ServletException {
calculationResult = threadPool.submit(new PreComputingTask());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String slowResponse = calculationResult.get();
//...
}
}
class PreComputingTask implements Callable<String> {
@Override
public String call() throws Exception {
//Call external systems, whatever...
return "slow response";
}
}
ご覧のとおり、servlet2
起動すると、別のスレッドで事前計算タスクが開始されます。次に、doGet()
まだ終了していない場合は、結果を取得し、おそらくそれを待っています。
事前計算が入力に依存している場合servlet1
(たとえば、外部システムを呼び出すときに使用する必要がある要求パラメーターservlet1
)、それははるかに困難で興味深いものです。
少なくとも 2 つのオプションがあります。
Future
でタスクを開始し、servlet1
その未来 (できれば既に完了している) を で取得しますservlet2
。たとえば、サーブレット間で何らかの方法で渡す必要があります。ServletContext
からjmsキューにメッセージを送信しますservlet1
。メッセージリスナーはリクエストを処理し、結果を事前に計算して、結果を一時的な一意のキューに入れます。servlet2
その後、後でそのキューからメッセージを受信するか (名前付けスキームに同意する必要があります)、少し待つことができます。