首先,看起来您正在修改
result两个线程中的对象。这不是线程安全的,因为
first和
second线程之间的操作可能彼此之间或运行servlet的线程之间不可见。有关更多信息,请参见本文。
其次,如果您正在其他线程中修改响应,则不会,这将是不安全的。退出
doGet方法后,应考虑发送的响应。在您的示例中,有可能在这两个线程运行之前将响应发送回客户端。
假设
MyResultresult影响了
response对象(您将添加
result到中
response,它正在影响响应代码,等等)。有几种方法可以解决此问题。
使用
ExecutorService
和Future
:public void doGet(HttpServletRequest request, HttpServletResponse response) {// Creating a new ExecutorService for illustrative purposes.
// As mentioned in comments, it is better to create a global
// instance of ExecutorService and use it in all servlets.
ExecutorService executor = Executors.newFixedThreadPool(2);Future
f1 = executor.submit(new Callable () {
@Override
public Result1 call() throws Exception {
// do expensive stuff here.
return result;
}
});Future
f2 = executor.submit(new Callable () {
@Override
public Result2 call() throws Exception {
// do expensive stuff here.
return result;
}
});// shutdown allows the executor to clean up its threads.
// Also prevents more Callables/Runnables from being submitted.
executor.shutdown();// The call to .get() will block until the executor has
// completed executing the Callable.
Result1 r1 = f1.get();
Result2 r2 = f2.get();
MyResult result = new MyResult();
// add r1 and r2 to result.
// modify response based on result
}一种更高级的技术是异步处理。如果您的请求需要很长时间才能处理,则使用异步处理是一个好主意。它不会提高任何一个请求的延迟,但是它确实允许Tomcat在任何给定时间点处理更多请求。
一个简单的例子是:
@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true)// Rather than @WebServlet, you can also specify these parameters in web.xml public class AsyncServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=UTF-8"); final AsyncContext acontext = request.startAsync(); acontext.start(new Runnable() { public void run() { // perform time consuming steps here. acontext.complete(); }}


