Sử dụng một ExecutorService. Có một vài điều bạn nên làm mặc dù, đánh dấu chủ đề như là một chủ đề daemon vì vậy nó atleast sẽ không tie tomcat trong các kịch bản lỗi, và bạn nên ngừng thực thi khi bối cảnh servlet của bạn bị phá hủy (ví dụ: khi bạn redeploy hoặc ngừng ứng dụng của bạn để làm điều này, sử dụng một ServletContextListener:.
public class ExecutorContextListener implements ServletContextListener {
private ExecutorService executor;
public void contextInitialized(ServletContextEvent arg0) {
ServletContext context = arg0.getServletContext();
int nr_executors = 1;
ThreadFactory daemonFactory = new DaemonThreadFactory();
try {
nr_executors = Integer.parseInt(context.getInitParameter("nr-executors"));
} catch (NumberFormatException ignore) {}
if(nr_executors <= 1) {
executor = Executors.newSingleThreadExecutor(daemonFactory);
} else {
executor = Executors.newFixedThreadPool(nr_executors,daemonFactory);
}
context.setAttribute("MY_EXECUTOR", executor);
}
public void contextDestroyed(ServletContextEvent arg0) {
ServletContext context = arg0.getServletContext();
executor.shutdownNow(); // or process/wait until all pending jobs are done
}
}
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* Hands out threads from the wrapped threadfactory with setDeamon(true), so the
* threads won't keep the JVM alive when it should otherwise exit.
*/
public class DaemonThreadFactory implements ThreadFactory {
private final ThreadFactory factory;
/**
* Construct a ThreadFactory with setDeamon(true) using
* Executors.defaultThreadFactory()
*/
public DaemonThreadFactory() {
this(Executors.defaultThreadFactory());
}
/**
* Construct a ThreadFactory with setDeamon(true) wrapping the given factory
*
* @param thread
* factory to wrap
*/
public DaemonThreadFactory(ThreadFactory factory) {
if (factory == null)
throw new NullPointerException("factory cannot be null");
this.factory = factory;
}
public Thread newThread(Runnable r) {
final Thread t = factory.newThread(r);
t.setDaemon(true);
return t;
}
}
bạn sẽ có thêm người nghe bối cảnh để web.xml của bạn, nơi bạn cũng có thể chỉ định số lượng bài bạn sẽ muốn chạy công việc nền:
<listener>
<listener-class>com.example.ExecutorContextListener</listener-class>
</listener>
Bạn có thể truy cập vào người thi hành từ servlet của bạn và gửi công ăn việc làm với nó:
ExecutorService executor = (ExecutorService)getServletContext().getAttribute("MY_EXECUTOR");
...
executor.submit(myJob);
Nếu bạn đang sử dụng Spring, tất cả điều này có lẽ có thể được thực hiện ngay cả simpler
bạn đang mong đợi để đưa ra một phản ứng trở lại? Ngoài ra, Tomcat sử dụng threadpools có thể mở rộng khi cần thiết để phục vụ nhiều yêu cầu đồng thời. –
Bạn có cần hiển thị kết quả của "yêu cầu khai thác dữ liệu" cho người dùng (hoặc ít nhất là thông báo cho họ về công việc đã hoàn thành) không? Và làm thế nào để bạn cần phải làm điều đó? –
Tôi đã nghĩ rằng khi công việc kết thúc, người dùng có thể được gửi email để nói rằng kết quả có sẵn. –