如何使用 scheduledexecutorservice 强制创建单线程并避免多线程
How to force to create a single thread using scheduledexecutorservice and avoid multithreading
我想在进入welcome.jsp页面时只执行一次下面的JAVA代码。
welcome.jsp:
<%WeeklyScheduledMail wsm = WeeklyScheduledMail.INSTANCE;
wsm.startThread(); %>
所以,如果一个用户在服务器启动后访问该网站,该代码只能使用一次,其他登录并访问welcome.jsp的用户将不会执行该JAVA代码。
首先,我尝试用枚举实现单例模式,我认为这就足够了,但没有成功。我也尝试了方法的 Synchronized 关键字,但没有...
我确定我做错了什么或者有更好的方法来做我想做的事。
部分代码:
WeeklyScheduledMail.java:
public enum WeeklyScheduledMail{
INSTANCE;
public void startThread() {
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
Runnable task = new TaskSendEmail();
int initialDelay = 0;
int periodicDelay = 10;
scheduler.scheduleAtFixedRate(task, initialDelay, periodicDelay,
TimeUnit.SECONDS);
}
}
TaskSendEmail.java:
public class TaskSendEmail implements Runnable{
public void run() {
System.out.println("Hello: "+System.currentTimeMillis());
}
}
您正在研究 运行 应用程序初始化代码的错误概念。 JSP 和其他向用户公开的资源并不是为此而设计的。即使您可以强制执行一些惰性初始化逻辑,仍然会有可避免的开销。
你要找的是 JavaEE 提供的:一个 context listener,它在应用程序启动时被调用一次,以通知你的应用程序上下文已经初始化:
public class MyContextListener implements javax.servlet.ServletContextListener {
private static fWeeklyScheduledMail wsm =
weeklyScheduledMail.INSTANCE;
@Override
public void contextInitialized(ServletContextEvent sce) {
wsm.startThread();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
wsm.stopThread();
}
}
然后必须在 web.xml
部署描述符(在 web-app
下)中注册此侦听器:
<listener>
<listener-class>my.packg.MyContextListener</listener-class>
</listener>
当应用程序启动时,上面的代码和配置将使您的日程安排 运行 一次。
我想在进入welcome.jsp页面时只执行一次下面的JAVA代码。
welcome.jsp:
<%WeeklyScheduledMail wsm = WeeklyScheduledMail.INSTANCE;
wsm.startThread(); %>
所以,如果一个用户在服务器启动后访问该网站,该代码只能使用一次,其他登录并访问welcome.jsp的用户将不会执行该JAVA代码。
首先,我尝试用枚举实现单例模式,我认为这就足够了,但没有成功。我也尝试了方法的 Synchronized 关键字,但没有...
我确定我做错了什么或者有更好的方法来做我想做的事。
部分代码:
WeeklyScheduledMail.java:
public enum WeeklyScheduledMail{
INSTANCE;
public void startThread() {
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
Runnable task = new TaskSendEmail();
int initialDelay = 0;
int periodicDelay = 10;
scheduler.scheduleAtFixedRate(task, initialDelay, periodicDelay,
TimeUnit.SECONDS);
}
}
TaskSendEmail.java:
public class TaskSendEmail implements Runnable{
public void run() {
System.out.println("Hello: "+System.currentTimeMillis());
}
}
您正在研究 运行 应用程序初始化代码的错误概念。 JSP 和其他向用户公开的资源并不是为此而设计的。即使您可以强制执行一些惰性初始化逻辑,仍然会有可避免的开销。
你要找的是 JavaEE 提供的:一个 context listener,它在应用程序启动时被调用一次,以通知你的应用程序上下文已经初始化:
public class MyContextListener implements javax.servlet.ServletContextListener {
private static fWeeklyScheduledMail wsm =
weeklyScheduledMail.INSTANCE;
@Override
public void contextInitialized(ServletContextEvent sce) {
wsm.startThread();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
wsm.stopThread();
}
}
然后必须在 web.xml
部署描述符(在 web-app
下)中注册此侦听器:
<listener>
<listener-class>my.packg.MyContextListener</listener-class>
</listener>
当应用程序启动时,上面的代码和配置将使您的日程安排 运行 一次。