Java 如何强制使用scheduledexecutorservice创建单个线程并避免多线程

Java 如何强制使用scheduledexecutorservice创建单个线程并避免多线程,java,jakarta-ee,java-threads,Java,Jakarta Ee,Java Threads,当我进入welcome.jsp页面时,我只想执行以下JAVA代码一次 welcome.jsp: <%WeeklyScheduledMail wsm = WeeklyScheduledMail.INSTANCE; wsm.startThread(); %> TaskSendEmail.java: public class TaskSendEmail implements Runnable{ public void run() { System.out.pri

当我进入welcome.jsp页面时,我只想执行以下JAVA代码一次

welcome.jsp:

<%WeeklyScheduledMail wsm = WeeklyScheduledMail.INSTANCE;
wsm.startThread(); %>
TaskSendEmail.java:

public class TaskSendEmail implements Runnable{

    public void run() {
        System.out.println("Hello: "+System.currentTimeMillis());
    }
}

您正在研究运行应用程序初始化代码的错误概念。JSP和其他向用户公开的资源不是为此而设计的。即使您可以强制执行一些延迟的初始化逻辑,仍然会有可以避免的开销

您要查找的内容由JavaEE:a提供,它在应用程序启动时被调用一次,以通知您的应用程序上下文已初始化:

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 app下的web.xml部署描述符中注册此侦听器:


上述代码和配置将使您的计划在应用程序启动时运行一次。

请尝试Webapplication事件,即contextInitialized。这将只在JSP中运行一次。从JSP管理此类功能似乎不是一个好主意,应该在应用程序启动时执行。@daniu我也这么认为,但是,当某些具有特定管理员角色的用户访问welcome.jsp页面时,我需要“触发”此Java代码。@Arvind有趣!你能解释一下这个过程吗?它不一定是我的代码,只是一个更发达的例子,以了解如何实现它。@Gera,请参阅文章实际做同样的事情它的工作!谢谢。但是,我想知道,如果发生某些特定事件,是否可以在一个线程或多个线程中执行类似的任务。当服务器启动时,侦听器正在初始化线程,但是…如果我希望在webapp中发生特定事件后初始化线程,该怎么办?@Gera其他事件的类型是什么?即当具有管理权限的用户单击特定页面内的按钮时。@Gera否,您可以使用事件进行初始化。为此,应该使用普通的应用程序代码servlet`doXyz1、JSF侦听器等。您也有用于用户会话的事件侦听器,但没有为处理用户交互而设计的侦听器。
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();
    }
}
<listener>
     <listener-class>my.packg.MyContextListener</listener-class>
</listener>