简短的问题: 在Tomcat 6应用程序中-如何运行(单独的)线程池?
运行线程池的最佳解决方案是什么?
长问题: 我这里有一个简单的需求; 轮询数据库以获取一些数据,同时允许Web客户端等待答案(长轮询连接)。 当数据库中有此数据时,我将向相关客户端发送回复。
这么说的话,我 宁愿 不潜入任何框架的时刻(quartz scheduler也许?)。
quartz scheduler
因此,正如我得出的结论,我需要一个线程池来在后台完成这项工作。
因此,如果Thread实际上是我要使用的东西Runnable,哪个班级可以组织这一切?有什么ThreadPool解决办法吗?有什么建议吗?
Thread
Runnable
ThreadPool
回答您的简短问题:
在JVM中,线程池是在java.util.concurrent.ExecutorService接口后面抽象的。该接口有不同的实现,但是在大多数情况下,该接口的方法就足够了。
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方法感兴趣。
java.util.concurrent.Executors
ExecutorService
newFixedThreadPool(int threadsNumber)
newCachedThreadPool
有关ExecutorsJVM中的更多常规信息,您可能需要阅读以下Oracle教程:http : //docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
Executors
因此,要ExecutorService在Tomcat下使用线程池(),您应该执行以下操作:
.1。如果尚未完成,请在接口web.xml实例中创建并注册该javax.servlet.ServletContextListener接口(这将充当您的Web应用程序的入口点)。
web.xml
javax.servlet.ServletContextListener
.2。在contextInitialized(ServletContextEvent)方法中,您创建ExecutorService(线程池)的实例并将其存储在ServletContext属性映射中,以便可以从您的webapp中的任何点访问它,例如:
contextInitialized(ServletContextEvent)
ServletContext
// following method is invoked one time, when you web application starts (is deployed) @Override public void contextInitialized(ServletContextEvent servletContextEvent) { // ... final int numberOfThreads = ...; final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads); // starts thread pool final ServletContext servletContext = servletContextEvent.getServletContext(); servletContext.setAttribute("threadPoolAlias", threadPool); // ... } // following method is invoked one time when your web application stops (is undeployed) public void contextDestroyed(ServletContextEvent servletContextEvent) { // following code is just to free resources occupied by thread pool when web application is undeployed final ExecutorService threadPool = (ExecutorService) servletContextEvent.getServletContext().getAttribute("threadPoolAlias"); threadPool.shutdown(); }
.3。某处在Servlet.service方法或任何地方你的webapp(你应该能够获得以基准ServletContext从Web应用程序几乎任何地方):
Servlet.service
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的引用,并可以从其他线程中查询它,以了解它是否已完成以及结果如何。
希望这可以帮助…