使用ExecutorService执行异步任务时出现问题

使用ExecutorService执行异步任务时出现问题

本文介绍了使用ExecutorService执行异步任务时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于ExecutorService和Apache Velocity,我曾向提出过
的问题初始化。为了快速回顾一下 - 我有一个接受用户请求的Java EE前端,然后对于每个请求,使用ExecutorService(设置为守护进程的SingleThreadedExecutor)启动冗长的工作流。此工作流包含在库中并且可以工作当通过eclipse在独立模式下运行时,正如预期的那样。当从网站(servlet)调用时,我观察到工作流一直在Velocity Engine初始化的位置(Velocity.init()或ve.init())。因此我提出了上述问题。

I had asked a question earlier regarding ExecutorService and Apache Velocity initialization. To give a quick recap -- I have a Java EE frontend which accepts user requests and then for each of these requests, uses ExecutorService(SingleThreadedExecutor set as a daemon) to kick off a lengthy workflow.This workflow is contained in a library and works well and as expected when run in a standalone mode through eclipse. When called from the website(servlet) I observed that the workflows were consistently getting hung at the point where the Velocity Engine was being initialized (Velocity.init() or ve.init()). Hence my aforementioned question.

当没有任何答案/建议有效时,我推断这与Velocity启动并决定转向FreeMarker的方式有关。现在我看到工作流程也悬挂在FreeMarker实现的完全相同的位置。这个'place'是邮件构建部分,它根据传递的数据对象的coupel评估模板并返回邮件字符串。调用Freemark'ing类和FreeMark类的类如下 -

When none of the answers/suggestions worked i inferred that this was something to do with the way Velocity started up and decided to shift to FreeMarker. Now i see that the workflow is getting hung in the exact same place for the FreeMarker implementation as well. This 'place' is the mail-building part which evaluates a template against a coupel of passed data objects and returns the mail string.The class that calls the Freemark'ing class and the FreeMark class are as follows --

   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类如下 -

FreeMarkIT class is as follows --

    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配置()

Now, from my logging it looks like the worker thread hangs at the lineconfig=new Configuration()

再次,这在预期的工作中如预期的那样从eclipse运行时的独立模式,但是当使用ExecutorService从servlet调用时挂起。

Again, this works as expected in a standalone mode when run from eclipse but however hangs when called from the servlet using ExecutorService.

我开始认为/意识到这可能与Velocity或者任何一个都无关FreeMarker与ExecutorService有关。
任何建议或建议都会有很大的帮助。

Im beginning to think/realize that this may have nothing to do with either of Velocity or FreeMarker and have something to do with ExecutorService.Any advice or suggestion would be of immense help.

谢谢

推荐答案

您的代码不是线程安全的,因为您在所有线程实例中共享 config template (并不断重新设置它们。使线程安全的最简单方法是在方法中使用 config 模板局部变量而不是静态成员。正如@JBNizet在评论中指出的那样,你在 mailBuilder 中遇到了类似的问题, a b'/ code>。您可能希望首先查看一些关于面向对象编程基础知识的教程,然后回过头来讨论这个问题(提示,一般情况下,除了常量之外,应该避免使用静态成员变量)。

your code is not thread-safe since you are sharing config and template across all thread instances (and continuously re-setting them). the easiest way to make it thread safe would be to make config and template local variables in the method instead of static members. as @JBNizet pointed out in the comments, you have a similar problem in mailBuilder with a and b. you might want to first check out some tutorials on object oriented programming fundamentals and then circle back to this issue (hint, in general you should avoid static member variables except for constants).

这篇关于使用ExecutorService执行异步任务时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 22:09