我有一个用于发送电子邮件的方法。我想锁定这个方法,这样每次只有一个线程可以访问它,其余的线程可以同时访问。我应该同步该方法还是使用 spring @transactional PROPAGATION_REQUIRED ?

在我的服务层

 //each time use new thread to send out email
  public  void sendThroughSMTP(List<String> emails,String subject,String content){

            //each time will open and sent through port 25.  dont u think this will caused too many threads spawned?
            BlastEmailThread blastEmailThread = new BlastEmailThread(emails,subject,content);

            blastEmailThread.start();


}
有帮助吗?

解决方案

为什么不把该方法是线程安全的,不使用任何实例层次的东西?

不过,我没有看到Spring的事务管理如何适应这里。我的意思是Spring提供几个事务管理器,即DataSourceTransactionManagerJtaTransactionManagerHibernateTransactionManager这一切都是关于数据库的持久性。你会为这个电子邮件配置什么送出去?

我认为,首先应该告诉我们,为什么你担心在首位的线程安全。最可能的是,你想向我们展示了一些相关的代码片段或东西。然后,我们也许能暗示你的东西。

<强> [附录]

当你正在产卵每次调用该方法的线程,并没有使用任何来自国家,那么为什么你想方法synchronized。制作同步将不以任何方式限制线程数的方法。可能有机会,开始一个新的线程之前,前一个线程可能已经结束,因为同步的工作。产生线程的进程可能会慢些。

然而,你应该与此去,直到你发现,有真正运行多个线程和你出去的内存。如果你真的想解决此时间之前,那么你应该选择一些阻塞机制,类似的旗语

其他提示

另一种可能性是使用JMS队列,并把电子邮件发送代码在驱动Bean(或者通过弹簧JMS)消息。那么你可以使用你的应用服务器来控制你的MDB的许多并发实例将被用来和节流外发电子邮件的方式。

在自旋微观3.0,您可以使用@Async注释做任务执行,所以你的方法将在后面执行,并直接返回该方法无需等待电子邮件发送。

@Async
public  void sendThroughSMTP(List<String> emails,String subject,String content){
//Send emails here, you can directly send lots of email
}

那么在应用程序上下文中指定,不要忘记添加的xmlns任务模式。

如果你想拖延一定的时间执行,你可以使用@Scheduled注解你的方法。

约@Async和@Scheduled此外教程可以在这里找到:

HTTP://博客.springsource.com / 2010/01/05 /任务调度简单化式 - 弹簧 - 3-0 /

我不确定它是否回答了您的问题,但是您可以拥有一个,而不是为每封邮件创建一个新线程并在其上调用 start 执行者 或者 执行服务 作为班级的成员,作为实现,您可以使用 线程池执行器 池大小为 1。然后,您的 sendMail 方法会将 Runnables 提交给执行程序。

春季@事务是不太正确的,你的情况使用。最好的办法是使用synchorized方法,并添加一些线程池,如果数以百计的时间叫你的方法。但我猜你不需要线程池在这里。

如果您使用的线程发送电子邮件爆炸,然后什么点同步的方法是什么?如果一个进程调用你的方法和发送电子邮件,其他进程将调用你的方法,即使第一发送电子邮件的过程尚未完成。

如果您有意节流电子邮件发送过程中,你需要condider队列(集合)和保护收集与同步块。创建另一个进程,以监督该队列,如果在队列中的一个项目,弹出它和发送电子邮件爆炸,然后等待,直到发送邮件的过程完成,并再次检查队列中,如果有任何项目,继续发送邮件的过程。如果队列中没有项目,使监视器线程睡眠的时间有些大块,这时如果睡眠时间完成再次检查队列。

请您服务singleton并添加synchronized到你的方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top