开始&使用servlet在Java EE环境中停止ScheduledExecutorService

时间:2014-08-11 06:36:53

标签: java java-ee scheduledexecutorservice start-stop-daemon

我们需要使用简单的servlet应用程序通过JMX监视远程JVM详细信息。所以直到现在在独立应用程序中完成的事情是

1)创建一个JMX连接器&获取内存数据 - > DONE 2)我们需要不断监控和得到记录 (2.1>可以被视为持续延迟的计划任务&将记录插入DB或2.2> JMX是否提供历史记录,如果是,哪个MBean可以访问该信息?)。

这里我打算使用一个界面来注册域,然后就可以了。有开始&来自JSP的停止按钮。我们点击启动系统时的功能将运行调度程序(ScheduledExecutorService)&捕获背景记录以提供历史记录。当使用点击停止时,调度程序必须停止后台进程。问题是我们如何控制和获取调度程序的对象?

1)换句话说,我们怎样才能开始&通过servlets停止ScheduledExecutorService?从一个servlet开始一个线程&从另一个servlet停止某个特定任务的线程?

2)如果我们有一个集群/负载均衡的环境怎么办?

目前我正在考虑将每个ScheduledExecutorService添加到HashMap中,关键是任务对象&值是使用SingleTon设计模式的ScheduledExecutorService。有没有默认方法。使用SingleTon的整个循环处于集群/负载平衡环境中,我们可能无法获得适当的更新对象。

期待您的宝贵建议。

2 个答案:

答案 0 :(得分:3)

如果在java ee 7上,请尝试使用javax.enterprise.concurrent.ManagedScheduledExecutorService

然后你可以进行资源注入并使用类似下面的代码启动任务。

@Resource
ManagedScheduledExecutorService mses;

public void startTask() {
    mses.scheduleAtFixedRate(runnable, 10, 10, SECONDS);
}

在Java EE 6中,您可以使用timerservice API

创建/删除servlet

答案 1 :(得分:1)

ServletContext

ServletContext表示您在Servlet容器中运行的整个Web应用程序。如Servlet spec所承诺的那样,在servlet处理第一个HTTP请求之前建立上下文。虽然HttpSession表示每个用户的工作会话(从技术上讲,是一个通过servlet代码的线程),但ServletContext表示所有这些用户的范围。

要挂钩servlet上下文的设置和拆除,请实现ServletContextListener。提示:通过使用@WebListener注释对其进行标记来自动部署侦听器。该接口需要一对方法,每个方法在您处理第一个Servlet请求之前以及当您的Web应用程序被拆除之前设置Web应用程序时调用。

提示:这种拆卸方法是关闭ScheduledExecutorService的好地方。在您的Web应用程序结束后,与您的执行程序服务关联的线程可能会存在。你可能不希望这种情况发生。

请参阅此问题:How to get and set a global object in Java servlet context

另请参阅BalusC的this nice summary of Servlet scope

获取servlet上下文

您可以首先访问其ServletConfig来访问当前servlet的ServletContext

// … in your Servlet, such as its request handler methods like `doGet` …
ServletContext sc = this.getServletConfig().getServletContext() ;

ServletContextListener中,我们如何访问servlet上下文?当调用侦听器上的两个方法中的任何一个时,将传递ServletContextEvent。从那里拨打ServletContextEvent::getServletContext()

将对象存储为servlet上下文中的“属性”

那么在哪里存储您的网络应用的全局变量,例如ScheduledExecutorService? servlet上下文具有StringObject的内置映射。这些被称为“属性”。调用setAttribute( String , Object )来存储属性映射。因此,为ScheduledExecutorService组成一个名称,以便在此地图中使用密钥。

ScheduledExecutorService sec = … ; // Instantiated somewhere in your code. 
…
String key = "myScheduledExecutorServiceForXYZ" ;
sc.setAttribute( key , sec );  // Storing the executor service as a generic `Object` for use later.

稍后您可以以同样的方式获取ScheduledExecutorService。您需要从Object转换为已知类,在本例中为ScheduledExecutorService

Object o = sc.getAttribute( key ); // Fetch the `ScheduledExecutorService` from the servlet context’s built-in map of attributes.

// Cast to known class. If in doubt, test first with [`instanceOf`][11].
ScheduledExecutorService sec = ( ScheduledExecutorService ) o ; 

您可以通过调用ServletContext::getAttributeNames来询问所有存储的属性名称列表。

范围图

这是我的图表,用于了解Servlet环境中范围的层次结构。请注意每个范围层如何具有其属性集,其自己的StringObject地图。在图表中,每组属性的生命周期都会缩短。

enter image description here