让javamail会话传输保持打开状态是否可以接受?

让javamail会话传输保持打开状态是否可以接受?,java,jakarta-mail,Java,Jakarta Mail,我的应用程序需要临时发送电子邮件。我正在使用javamail的getDefaultSession和getTransport发送消息,并且一切正常 但是我注意到发送可能需要很长时间-每次发送最多7秒。如果我把台阶拆下来,像这样: Transport transport = session.getTransport("smtp"); transport.connect(); transport.sendMessage( msg, addresses ) transport.close(); Tra

我的应用程序需要临时发送电子邮件。我正在使用javamail的getDefaultSession和getTransport发送消息,并且一切正常

但是我注意到发送可能需要很长时间-每次发送最多7秒。如果我把台阶拆下来,像这样:

Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage( msg, addresses )
transport.close();
Transport transport = session.getTransport("smtp");
if (!transport.isConnected())
    transport.connect();
transport.sendMessage( msg, addresses )
…我可以看出,每次调用connect()几乎占用了所有的时间

我发现的所有示例都是这样做的——获取传输、连接、发送、断开连接。当然,它们都是一次性的例子,或者在一次通话中发送大量电子邮件

我在想我可以保持连接打开,就像这样:

Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage( msg, addresses )
transport.close();
Transport transport = session.getTransport("smtp");
if (!transport.isConnected())
    transport.connect();
transport.sendMessage( msg, addresses )
(这里有一个变体:)

我最终不得不关闭它,在某种关闭挂钩中。而且我可能不得不有一个后备方案(如果连接已经丢失,但交通部门没有意识到)。但是,在应用程序生命周期中,有什么理由不让它像这样打开吗

谢谢,
Alastair

我认为保持单个SMTP连接打开没有任何问题,建议使用Transport对象以重用连接(请参阅)


此外,我建议您在应用程序中只保持一个smpt连接(通过传输)处于打开状态,将其保持在单个manager实例中(即使用单例模式),避免为每个需要发送消息的组件保持不同连接的最终成本。

根据
@Bill Shannon
(JavaMail的作者)回答如下:

由于传输表示到邮件服务器的连接,并且一次只能有一个线程使用该连接,因此传输将同步来自多个线程的访问以维护线程安全,但您实际上只希望从单个线程使用它


因此,如果您计划使用来自多线程的单个
传输
实例(现在通常是这种情况)实际上,从性能的角度来看,这是一个非常糟糕的主意。你最好使用
ThreadLocal
,开发一些
传输
实例池,谢谢你,这正是我所希望的。我确实计划在一个单一的“EmailSender”插件中使用它例如,这应该没问题。这种方法可能会在多线程环境中导致严重的性能问题,如我的回答中所述。如果有人需要这样的池的代码示例-请在这里留下评论,我将用itHello Yura扩展我的回答,我对一些示例感兴趣,实际上我开发了一个针对阅读邮件的代码,其中包含问题使用来自多线程的imap,我的会话在单例ejb中,但用于访问邮件信息的其他代码在无状态ejb中。非常感谢。@Gaalvarez这可能会对您有所帮助,如果您确实需要,只需将池大小设置为1即可: