Utilizzare un ExecutorService.
Ci sono alcune cose che dovresti fare, contrassegnare il thread come un daemon thread in modo che almeno non leghi tomcat in scenari di errore, e dovresti interrompere l'executor quando il contesto del servlet è distrutto (ad esempio quando ridistribuisci o interrompere l'applicazione per fare questo, utilizzare un 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;
}
}
dovrete aggiungere il listener contesto al vostro web.xml, in cui è anche possibile specificare il numero di thread si desidera eseguire i lavori in background:
<listener>
<listener-class>com.example.ExecutorContextListener</listener-class>
</listener>
È possibile accedere l'esecutore dal servlet e inviare i lavori ad esso:
ExecutorService executor = (ExecutorService)getServletContext().getAttribute("MY_EXECUTOR");
...
executor.submit(myJob);
Se stai usando primavera, tutto questo può probabilmente essere reso ancora simpler
Ti aspetti di dare una risposta indietro? Inoltre, Tomcat utilizza threadpool che possono espandersi quando necessario per soddisfare più richieste simultanee. –
È necessario visualizzare i risultati delle "richieste di data mining" agli utenti (o almeno notificarli dei lavori completati)? E come hai bisogno di farlo? –
Stavo pensando che quando un lavoro è finito, l'utente può essere inviato via email per dire che i risultati sono disponibili. –