如何在Java或Groovy中处理并发性

如何在Java或Groovy中处理并发性,java,groovy,Java,Groovy,我有一段代码来发送邮件,在发送邮件之前,我必须用当前登录的用户电子邮件覆盖默认的smtp设置,在我必须还原它之后,因此当两个或多个用户尝试发送邮件时,会出现并发问题,因此如何消除此问题。一般来说(因为您没有提供代码):如果多个线程以配置-然后使用的方式使用单个资源,则应将数据放入对象(new-MailSendRequest(smtpconfig,message)')并将其放入队列。另一个线程应监视此队列,并绕过并发问题逐个处理邮件发送请求。(在这种特定情况下,无论如何都应该延迟发送邮件,因为IS

我有一段代码来发送邮件,在发送邮件之前,我必须用当前登录的用户电子邮件覆盖默认的smtp设置,在我必须还原它之后,因此当两个或多个用户尝试发送邮件时,会出现并发问题,因此如何消除此问题。

一般来说(因为您没有提供代码):如果多个线程以配置-然后使用的方式使用单个资源,则应将数据放入对象(
new-MailSendRequest(smtpconfig,message)
')并将其放入队列。另一个
线程应监视此队列,并绕过并发问题逐个处理
邮件发送请求。(在这种特定情况下,无论如何都应该延迟发送邮件,因为ISP-s认为一次性发送大量邮件不是一种好做法。他们通常定期发送小批量邮件。)

第一种方式: 你需要锁定。以下是我要做的:

void sendMail(){
    syncronize(smtp){
       //alter smtp mail object
       smtp.sentMail();
       //revert smtp mail object
    }
}
当代码执行进入
syncronize
block时,它会锁定smtp对象,然后无论谁来到锁定的对象,都会等待它得到解决

第二种方式: 或者使用共享的
对象

Lock lock = new ReentrantLock();
void sendMail(){
       lock.lock();
       //alter smtp mail object
       smtp.sentMail();
       //revert smtp mail object
      lock.unLock(); 
    }
}


这是一种交易

jabal的解决方案也正是我所建议的。具体来说,我建议您使用该服务。它完全符合jabal的建议:您可以将邮件请求排队,一个线程将按顺序处理它们


但我注意到,您正在处理一个可能存在高延迟问题的任务(将此任务放在其他队列上的一个很好的原因!)。我建议您确保明确地知道任务应该花费的最长时间,并确保您知道您的执行者的身份,以便您可以处理在执行过程中遇到的任何潜在错误。

任何类型的代码都可以执行此操作,以便我们可以看到您正在尝试执行什么?为什么要重写然后还原?为什么有必要?请尝试gpgroovy的ars。应该具备您所需要的功能。您更喜欢此解决方案中的哪一个
ReentrantLock
更强大,但在这里我将使用第一个解决方案。我相信
syncronized(smtp)
正是为了实现这种目的。