Utiliser un ExecutorService .
Il y a quelques choses que vous devriez faire cependant, marquer le thread comme un thread démon pour qu'il ne bloque pas tomcat dans les scénarios d'erreur, et vous devriez arrêter l'exécuteur quand votre contexte de servlet est détruit (par exemple quand vous redéployez ou arrêtez votre application). Pour ce faire, utilisez 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;
}
}
Vous devrez ajouter l'écouteur de contexte à votre fichier web.xml, où vous pourrez également spécifier le nombre de threads nécessaires à l'exécution des tâches d'arrière-plan :
<listener>
<listener-class>com.example.ExecutorContextListener</listener-class>
</listener>
Vous pouvez accéder à l'exécuteur à partir de votre servlet et lui soumettre des tâches :
ExecutorService executor = (ExecutorService )getServletContext().getAttribute("MY_EXECUTOR");
...
executor.submit(myJob);
Si vous utilisez Spring, tout cela peut probablement être rendu encore plus facile. plus simple