在像Tomcat或Jetty这样的准系统servlet容器中,最安全的选择是使用最大 的applicaton宽 ,以便在必要时将任务排队。该ExecutorService
是在这个非常有帮助。
在应用程序启动或servlet初始化后,使用Executors
该类创建一个:
executor = Executors.newFixedThreadPool(10); // Max 10 threads.
然后在servlet的服务期间(对于您不感兴趣的情况,您可以忽略结果,或将其存储在会话中以供以后访问):
Future<ReturnType> result = executor.submit(new YourTask(yourData));
当YourTask
必须实现Runnable
或者Callable
,可以是这个样子,因此yourData
只是你的数据,例如由请求参数值(一定要记住,你绝对不应该通过Servlet API的工件,如HttpServletRequest
或HttpServletResponse
沿!):
public class YourTask implements Runnable {
private YourData yourData;
public YourTask(YourData yourData) {
this.yourData = yourData;
}
@Override
public void run() {
// Do your task here based on your data.
}
}
最后,在应用程序关闭或servlet销毁期间,您需要显式关闭它,否则线程可能会永远运行并阻止服务器正常关闭。
executor.shutdownNow(); // Returns list of undone tasks, for the case that.
如果您实际上使用的是通常可以使用EJB的普通JEE服务器(例如WildFly,Payara,TomEE等),则可以将@Asynchronous
注释放在从Servlet调用的EJB方法上。您可以选择让它返回Future<T>
带有的AsyncResult<T>
具体值。
@Asynchronous
public Future<ReturnType> submit() {
// ... Do your job here.
return new AsyncResult<ReturnType>(result);
}