2010-09-08 108 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