使用特殊线程发送邮件

发布于 2024-12-14 11:30:41 字数 206 浏览 2 评论 0原文

我有一个在 tomcat 6.0 上运行的 jsf 应用程序,在应用程序的某个位置我向一些用户发送电子邮件。但是发送邮件比我想象的要慢,它导致这些相关页面之间缺少。

所以我的问题是;这是一种很好的(或可行的)方法来将此过程交给我创建的另一个线程,该线程获取邮件发送请求并将这些请求放入队列中,并在主应用程序之外处理这些请求。因此,邮件发送过程将结束主要流程,不会影响应用程序的速度。

i have a jsf application running on tomcat 6.0 and somewhere in the app i send e mails to some users.But sending mail slower than i thought, it causes lacks beetwen these related pages.

So my question is; is that a good(or doable) a way to give this proccess to another thread which i create, a thread that gets mail sending requests and put these in a queue and proccess these apart from main application.Hence the mail sending proccess would be out of the main flow and doesnt affect the app's speed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡看悲欢离合 2024-12-21 11:30:41

是的,这绝对是个好主意。您应该非常小心地进行此操作。这里有一些值得思考的地方:

由于您使用的是 Tomcat,它不支持开箱即用的 EJB(因此 @Asynchronus @Singleton 是不可能的),我将创建一个应用程序范围的 bean,其中包含 ExecutorService 处理邮件任务。这是一个启动示例:

@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();
    }

}

这将创建一个线程并将任务放入队列中。您可以在普通 bean 中使用它,如下所示:

@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).
    }

}

要了解有关 java.util.concurrent API 的更多信息,请参阅 官方教程

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文