回答你的问题:
JVM中的线程池是通过 java.util.concurrent.ExecutorService
接口抽象的。尽管有不同的接口实现,但在大多数情况下,该接口的方法就足够使用了。
要创建特定的线程池,请查看 java.util.concurrent.Executors
类:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html
其中包含用于创建不同 ExecutorService 接口实现的静态工厂方法。您可能会对 newFixedThreadPool(int threadsNumber)
和 newCachedThreadPool
方法感兴趣。
关于 JVM 中的 Executors
的更一般信息,您可以阅读 Oracle 的教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
因此,在 Tomcat 下使用线程池(ExecutorService
)应按以下步骤执行:
1. 如果尚未完成,请在 web.xml
中创建并注册 javax.servlet.ServletContextListener
接口的实例(它将充当您的 Web 应用程序的入口点)。
2. 在 contextInitialized(ServletContextEvent)
方法中,创建 ExecutorService
实例(线程池),并将其存储在 ServletContext
属性映射中,以便可以从您的 Web 应用程序的任何点访问它,例如:
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
final int numberOfThreads = ...;
final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads);
final ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("threadPoolAlias", threadPool);
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
final ExecutorService threadPool = (ExecutorService) servletContextEvent.getServletContext().getAttribute("threadPoolAlias");
threadPool.shutdown();
}
3. 在Servlet.service
方法中的任何地方或者在你的webapp中的任何位置(你几乎可以从webapp中的任何地方获取对ServletContext
的引用):
Callable<ResultOfMyTask> callable = new Callable<ResultOfMyTask>() {
public ResultOfMyTask call() {
// here goes your task code which is to be invoked by thread pool
}
};
final ServletContext servletContext = ...;
final ExecutorService threadPool = (ExecutorService) servletContext.getAttribute("threadPoolAlias");
final Future<ResultOfMyTask> myTask = threadPool.submit(callable);;
你应该存储对myTask的引用,并可以从其他线程查询它是否完成以及结果是什么。
希望这有所帮助...