2010-09-08 134 views
0

我正在使用Quartz Scheduler v1.8.3并已集成到Apache Tomcat v6.0.10中,因此调度程序为initialized from within servlet container。作业也从Apache Tomcat中添加/调度到调度程序。作为客户端推荐调度程序的推荐方式是什么?

我设计从那里我只希望看到像meta-data值调度信息的JSP Web前端页面(quartzAdmin.jsp),其触发,当前执行工作等

沿着所有工作细节我的问题是,为了得到一个处理调度,下面的2选项哪一个建议:

方案1:通过直接调用schedulerFactory.getScheduler()获取手柄

SchedulerFactory sf = new StdSchedulerFactory(); 
Scheduler scheduler = sf.getScheduler(); 

方案2:通过我的quartzAdmin.jsp

public class Quartz { 

    private Quartz() { 
    } 

    private static Scheduler scheduler = null; 

    public static Scheduler getScheduler() { 
     if(scheduler == null) { 
      SchedulerFactory sf = new StdSchedulerFactory(); 
      scheduler = sf.getScheduler(); 
     } 
     return scheduler; 
    } 
} 

然后实现单件模式,只需要打一个电话Quartz.getScheduler获取手柄()将返回的句柄调度。

+0

上初始化石英一个相关的问题:http://stackoverflow.com/questions/3257074/whats-the-best-way-to -initalize-quartz – Gnanam 2010-09-08 13:56:02

回答

0

你在这里描述的是一个单例模式,并且你的单例初始化不是线程安全的。

我建议不要在这里使用单身人士,而是将Quartz的引用添加到ServletContext,可能会将其初始化为ServletContextListener

的web.xml

<listener> 
    <listener-class>my.package.MyServletContextListener</listener-class> 
</listener> 

MyServletContextListener.java

package my.package; 

public class MyServletContextListener implements ServletContextListener 
{ 
    @Override 
    public final void contextInitialized (
      final ServletContextEvent event 
     ) 
    { 
     final ServletContext servlet_ctx = event.getServletContext(); 

     Quartz quartz = new Quartz(); 

     servlet_ctx.addAttribute(Quartz.ATTRIBUTE_NAME, quartz); 
    } 

    @Override 
    public void contextDestroyed (
      final ServletContextEvent event 
     ) 
    { 
     final ServletContext servlet_ctx = event.getServletContext(); 

     Quartz.fromContext(servlet_ctx).shutdown(); 

     servlet_ctx.removeAttribute(Quartz.ATTRIBUTE_NAME); 
    } 
} 

Quartz.java

public final static String ATTRIBUTE_NAME = Quartz.class.getName(); 

public Quartz() 
{ 
    ... 
} 

public static Quartz fromContext(final ServletContext ctx) 
{ 
    return ctx.getAttribute(ATTRIBUTE_NAME); 
} 

public void shutdown() 
{ 
    ... 
} 
+0

假设除了获得与调度程序相关的信息之外,我不用调度器来操作任何东西,它是否仍然应该是线程安全的?希望你在这方面的意思是“不是线程安全的”,我是对的吗?另外,我无法清楚地理解你提到的建议。你能用一些简单的代码示例来解释吗? – Gnanam 2010-09-08 14:10:55

+1

@Gnanam。如果你打算直接从JSP调用原始的getScheduler()方法(不推荐),它肯定会从多个线程中调用。检查此文章正确的方式来初始化单例:http://stackoverflow.com/questions/3635396/pattern-for-lazy-thread-safe-singleton-instantiation-in-java/3635619#3635619 – 2010-09-08 16:41:05

0

我认为这两个选项都会创建一个新的调度程序,但不会获得您在web.xml中配置的调度程序。

目前,我这样做(类似于选项1):

 
...configure a QuartzInitializerListener for my webapp... 
// my servlet's init() 
public void init(ServletConfig config) throws ServletException { 
    ... 
    SchedulerFactory factory = 
      (SchedulerFactory) config.getServletContext().getAttribute(
       QuartzInitializerListener.QUARTZ_FACTORY_KEY 
      ); 
    Scheduler factory.getScheduler(); 
    ... 
} 
+1

不,我越来越调度程序的句柄,它是从'web.xml'初始化的。我可以使用'scheduler来验证这一点。getMetaData()。getSummary()'并检查这一行'从此开始:xxxxx' – Gnanam 2010-09-08 14:02:24

+0

我相信Quartz调度器本身已经考虑到了这一点。 – Gnanam 2010-09-08 14:04:13

+1

那么,就不需要使用单例,因为Quartz正在处理这个问题。只需使用选项1。 – gpeche 2010-09-08 14:21:33