Yes, that's definitely a good idea. You should only do it with an extreme care. Here's some food for thought:
As you're using Tomcat, which does not support EJB out the box (and thus @Asynchronus
@Singleton
is out of question), I'd create an application scoped bean which holds an ExecutorService
to process the mail tasks. Here's a kickoff example:
@ManagedBean(eager=true)
@ApplicationScoped
public class TaskManager {
private ExecutorService executor;
@PostConstruct
public void init() {
executor = Executors.newSingleThreadExecutor();
}
public <T> Future<T> submit(Callable<T> task) {
return executor.submit(task);
}
// Or just void submit(Runnable task) if you want fire-and-forget.
@PreDestroy
public void destroy() {
executor.shutdown();
}
}
This creates a single thread and puts the tasks in a queue. You can use it in normal beans as follows:
@ManagedBean
@RequestScoped
public class Register {
@ManagedProperty("#{taskManager}")
private TaskManager taskManager;
public void submit() {
// ...
taskManager.submit(new MailTask(mail));
// You might want to hold the return value in some Future<Result>, but
// you should store it in view or session scope in order to get result
// later. Note that the thread will block whenever you call get() on it.
// You can just ignore it altogether (as the current example is doing).
}
}
To learn more about java.util.concurrent
API, refer the official tutorial.