java一次只运行一个实例
我正在使用Java(Servlet,JSP)开发一个web应用程序 我有一个发送电子邮件的班 类看起来像:java一次只运行一个实例,java,multithreading,jakarta-mail,Java,Multithreading,Jakarta Mail,我正在使用Java(Servlet,JSP)开发一个web应用程序 我有一个发送电子邮件的班 类看起来像: public class EmailSender { String SendEmail(String from,Session session,String To,String CC, String BCC, String Subject,String Body) { //Actual code for sending emails } } Ema
public class EmailSender
{
String SendEmail(String from,Session session,String To,String CC, String BCC, String Subject,String Body)
{
//Actual code for sending emails
}
}
EmailSender
类是从另一个类调用的:
public class InvokeSender
{
public InvokeSender(String dbFileName)
{
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
}
}
当用户单击按钮时,将从servlet调用InvokeSender
当用户单击按钮时,调用InvokeSender,它从数据库接收要发送的电子邮件并形成它们,然后将这些参数传递给EmailSender
类的SendEmail()
我希望一次只运行一个InvokeSender
实例,以避免在按下两次按钮时相同的电子邮件发送两次。如何处理?在这种情况下,多线程
有用吗
如有任何建议,将不胜感激
更新1
我无法在用户单击按钮后禁用它。因为如果用户刷新页面,则默认情况下将启用该按钮
更新2
第一个用户选择发送电子邮件的客户、模板等,然后将电子邮件参数存储在数据库中InvokeSender
class获取要发送的所有电子邮件。无法预测要发送的电子邮件数量。它可以是1或500或更多。我只想运行InvokeSender
的一个实例,直到上一个实例完成发送电子邮件为止。功能(生成和发送电子邮件的按钮)将向5-7名用户公开。您可以使用队列数据结构将发送电子邮件请求排队,并在单独的线程中处理相同的请求。此线程将在启动期间生成一次,并将处理队列。发送电子邮件时,将清除状态='NOTSENT'
,这将解决多个电子邮件问题。队列可以按固定的时间间隔进行处理,也可以轮询数据,或者使用某种信号发送机制在队列中有数据时向线程发送信号
编辑:我认为此解决方案适合更新1和更新2您可以使用队列数据结构将发送电子邮件请求排队,并在单独的线程中处理。此线程将在启动期间生成一次,并将处理队列。发送电子邮件时,将清除状态='NOTSENT'
,这将解决多个电子邮件问题。队列可以按固定的时间间隔进行处理,也可以轮询数据,或者使用某种信号发送机制在队列中有数据时向线程发送信号
编辑:我认为此解决方案适合更新1和更新2我会在InvokeSender中使用原子布尔值,然后执行以下操作:
public class InvokeSender
{
static AtomicBoolean sendInProgress = new AtomicBoolean(false);
public InvokeSender(String dbFileName)
{
if (sendInProgress.compareAndSet(false, true)) {
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
sendInProgress.set(false);
}
}
}
当然,这是一个非常简单的解决方案,如果您想要更复杂的行为,如限制上一封电子邮件和下一封电子邮件之间的时间,您必须为此添加更多的逻辑。我将在InvokeSender中使用原子布尔,然后执行以下操作:
public class InvokeSender
{
static AtomicBoolean sendInProgress = new AtomicBoolean(false);
public InvokeSender(String dbFileName)
{
if (sendInProgress.compareAndSet(false, true)) {
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
sendInProgress.set(false);
}
}
}
当然,这是一个非常简单的解决方案,如果你想要更复杂的行为,比如限制上一封邮件和下一封邮件之间的时间,你就必须增加一些逻辑性。我认为,可以通过为页面创建一个会话范围为的唯一令牌来完成,该页面在Servlet类中具有电子邮件发送者和单例映射,以维护令牌
创建一个servlet过滤器,为页面生成会话范围内的令牌
如果标记在映射中不存在,则将该标记添加到
映射并调用邮件发送者
如果包含,则不要调用邮件
寄件人
我认为,可以通过为页面创建一个唯一的令牌,该令牌的会话范围为email sender和Servlet类中的单例映射来维护令牌
创建一个servlet过滤器,为页面生成会话范围内的令牌
如果标记在映射中不存在,则将该标记添加到
映射并调用邮件发送者
如果包含,则不要调用邮件
寄件人
使用同步化块
public InvokeSender(String dbFileName)
{
synchronized(InvokeSender.class){
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
}
}
使用同步化块
public InvokeSender(String dbFileName)
{
synchronized(InvokeSender.class){
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
}
}
在用户单击按钮后简单地禁用按钮怎么样?禁用按钮是一个好主意,但是我认为其目的是构建一个对UI没有依赖性的健壮的服务器组件。例如,您可能希望通过web服务接口公开此功能。@Joe请参阅update1
如何进行ajax调用(发送针对用户发送的电子邮件并将电子邮件存储在表中),并禁用该按钮。在页面加载时,检查是否未发送电子邮件,如果用户已发送邮件,则启用按钮?@Bhushan,直到您希望在多长时间内不向他发送下一封邮件。实现将取决于此。在用户单击按钮后简单地禁用按钮如何?禁用按钮是一个好主意,但是我认为其目的是构建一个对UI没有依赖性的健壮服务器组件。例如,您可能希望通过web服务界面公开此功能。@Joe请参阅update1
如何进行ajax调用(发送电子邮件并将针对用户发送的电子邮件存储在表中)并禁用该按钮。在页面加载时,检查是否未发送电子邮件,如果用户已发送邮件,则启用按钮?@Bhushan,直到您希望在多长时间内不向他发送下一封邮件。实施将取决于这一点。