Проблема при выполнении асинхронных задач с использованием ExecutorService - PullRequest
0 голосов
/ 01 января 2012

Я задавал вопрос ранее относительно инициализации ExecutorService и Apache Velocity.Для краткого обзора - у меня есть интерфейс Java EE, который принимает запросы пользователей, а затем для каждого из этих запросов использует ExecutorService (SingleThreadedExecutor, установленный в качестве демона), чтобы запустить длительный рабочий процесс. Этот рабочий процесс содержится в библиотеке и работаетну и как положено при запуске в автономном режиме через затмение.Когда меня вызывали с веб-сайта (сервлет), я заметил, что рабочие процессы постоянно зависали в момент инициализации Velocity Engine (Velocity.init () или ve.init ()).Отсюда мой вышеупомянутый вопрос.

Когда ни один из ответов / предложений не сработал, я предположил, что это как-то связано с тем, как 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()

Опять же, это работает как ожидалосьв автономном режиме, когда запускается из затмения, но, тем не менее, зависает при вызове из сервлета с использованием ExecutorService.

Я начинаю думать / осознавать, что это может не иметь ничего общего ни с Velocity, ни с FreeMarker и иметь какое-либо отношение кExecutorService.Любой совет или предложение будут иметь огромную помощь.

Спасибо

1 Ответ

3 голосов
/ 01 января 2012

ваш код не является потокобезопасным, поскольку вы совместно используете config и template во всех экземплярах потока (и постоянно их переустанавливаете). Самый простой способ сделать его потокобезопасным - создать в методе локальные переменные config и template вместо статических членов. Как отметил @JBNizet в комментариях, у вас есть похожая проблема в mailBuilder с a и b. Возможно, вы захотите сначала ознакомиться с некоторыми учебными пособиями по основам объектно-ориентированного программирования, а затем вернуться к этой проблеме (подсказка, как правило, вам следует избегать статических переменных-членов, за исключением констант).

...