2012-01-01 90 views
0

關於ExecutorService和Apache Velocity初始化,我曾問過一個關於earlier 的問題。爲了快速回顧一下 - 我有一個接受用戶請求的Java EE前端,然後對於每個請求,使用ExecutorService(SingleThreadedExecutor設置爲守護進程)啓動冗長的工作流。此工作流包含在庫中,並且可以工作以及通過eclipse在獨立模式下運行時的預期。當從網站(servlet)調用時,我發現工作流在Velocity Engine被初始化(Velocity.init()或ve.init())時一直處於掛起狀態。因此我提到了上述問題使用ExecutorService執行異步任務時發出的問題

當沒有一個答案/建議奏效時,我推斷這與Velocity啓動的方式有關,並決定轉移到FreeMarker。現在我發現工作流程也在FreeMarker實施的完全相同的地方被掛起。這個'地方'是郵件構建部分,其針對傳遞的數據對象的排序來評估模板並返回郵件字符串。調用Freemark'ing類和FreeMark類的類如下 -

public class mailBuilder { 

    private static final Logger log = Logger.getLogger(mailBuilder.class);  
    static String a; 
    static String b; 

    public mailBuilder(CustomDataStructure input) 
    { 
     a = input.getA(); 
     b = input.getB(); 
    } 
    public static String returnMailstring() throws Exception 
    { 
     log.info("Gathering elements to construct email."); 
     String mailText=null; 
     Map context = new HashMap(); 
     context.put("a",a); 
     context.put("b",b); 
     log.info("Calling Freemarker"); 
     mailText=FreeMarkIT.ReturnReportString(context); 
     log.info("Freeemarker returned string"); 

     return mailText; 
    } 
} 

FreeMarkIT類是如下 -

public class FreeMarkIT { 
     private static final Logger log = Logger.getLogger(FreeMarkIT.class); 
     private static Configuration config; 
     private static Template template; 

     public static String ReturnReportString(Map model) throws IOException, TemplateException 
     { 
      StringWriter sw = new StringWriter(); 
      try 
      { 
       log.info("Going to get the template"); 
       config= new Configuration(); 
       log.info("Now really"); 
       template=config.getTemplate("src/resource/email_template.vm"); 
       log.info("Done initializing template"); 
       template.process(model, sw); 
       sw.flush(); 
      } 
      catch(Exception e) 
      { 
       System.out.println(e.getMessage()); 
      } 

      return sw.getBuffer().toString(); 
     } 
    } 

現在,從我的記錄,它看起來像工作者線程在該行掛起 config=new Configuration()

再次,這將按預期在獨立模式下運行從當eclipse,但是當使用ExecutorService從servlet調用時會掛起。

我開始想/認識到這可能與Velocity或FreeMarker無關,並與ExecutorService有關。 任何建議或建議將有巨大的幫助。

感謝

+0

您的代碼不是有效的Java代碼。可以肯定的是,它遠不是線程安全的。向我們展示真實的代碼,因爲我們可能對假代碼進行的所有更正都不會有用。請尊重Java命名約定:您的代碼很難閱讀。 – 2012-01-01 13:52:39

+0

我很抱歉。我現在已經修復了這些代碼。 – ping 2012-01-01 14:04:44

回答

3

你的代碼是不是線程安全的,因爲你是共享configtemplate所有線程實例(不斷重新設置它們)。使線程安全的最簡單方法是在方法中使用configtemplate局部變量而不是靜態成員。正如@JBNizet在評論中指出的那樣,您在mailBuilderab有類似的問題。你可能想首先查看一些關於面向對象編程基礎的教程,然後回到這個問題上(提示,一般來說你應該避免除了常量之外的靜態成員變量)。

+3

+1。 mailBuilder中的變量a和b以及returnMailstring方法也不應該是靜態的。 – 2012-01-01 14:08:10

+0

啊,但不會有隻有一個線程訪問他們,因爲ExecutorService是一個SingleThreadedExecutor的事實? 我現在試着你的建議。 – ping 2012-01-01 14:09:10

+2

我們還沒有看到你如何使用你的執行者。您至少有兩個線程:請求處理線程和工作線程。你的代碼不僅非線程安全,而且設計不好。從解決設計問題開始,至少看看它是否解決了問題。 – 2012-01-01 14:12:25