почему классы действий Struts не являются потокобезопасными? - PullRequest
7 голосов
/ 17 февраля 2011

Я могу прочитать на многих веб-сайтах, что классы Struts Action не являются поточно-ориентированными. Я не могу понять, почему это так.

Также я прочитал книгу, в которой написано "Классы действий Struts кэшируются и используются повторно для повышения производительности. оптимизация за счет необходимости реализации классов действий потокобезопасным способом "

как связаны классы кэширования и безопасность потоков? .

Ответы [ 4 ]

24 голосов
/ 18 февраля 2011

Как кешируются классы действий и связаны с безопасностью потоков?

Если вы кэшируете и повторно используете экземпляры класса, позволяя нескольким потокам одновременно обращаться к одному и тому же экземпляру, тогда класс по своей природе не поточно-безопасный *. Если бы вы поместили изменяемый экземпляр или статические поля в класс, результаты в условиях параллелизма были бы неожиданными и проблематичными. С другой стороны, если у каждого потока есть свой экземпляр класса, этот класс по своей природе является поточно-ориентированным.

  • Классы действий Struts 1 не являются поточно-ориентированными. Не следует помещать какие-либо изменяемые поля в класс, вместо этого используйте класс Form Bean для полей формы, передаваемых действию.
  • Классы действий Struts 2 являются поточно-ориентированными. Новые экземпляры создаются для каждого запроса, и размещение полей экземпляра в классе является основной концепцией в рамках.

* Если экземпляр или статическое поле являются неизменяемыми, то хорошо, если несколько потоков будут иметь к ним доступ одновременно.

5 голосов
/ 17 февраля 2011

если какой-либо класс кэшируется и используется повторно, существует риск повреждения из-за одновременного доступа нескольких потоков. В веб-приложении каждый запрос обрабатывается в потоке. Допустим, у вас есть 10 экземпляров действия, но ваш контейнер обрабатывает 20 запросов - в этом случае каждое из 10 действий используется повторно, потому что у вас в запросе больше запросов, чем действий, доступных для их обслуживания.

Проблема безопасности потока возникает только в том случае, если в действии используется какое-то состояние. Если это так, то действие, обслуживающее один запрос, может установить значение в общей переменной, но тогда другой поток может вступить во владение, и действие снова может изменить общую переменную. В этом случае, когда первоначальный поток вступает во владение, общее состояние было изменено.

Простой способ справиться с этим - настроить свой стек так, чтобы он всегда использовал новое действие, или чтобы в ваших действиях не было общего состояния.

2 голосов
/ 17 февраля 2011

Почему бы не создать новый объект "action" для каждого запроса? Что в мире ??

Поскольку Struts настолько стар, он считает, что создание еще одного объекта на цикл запроса обходится так же дорого, как оплата доллара за кофе. (это очень дорого. потому что он действительно старый.)

1 голос
/ 06 февраля 2012

Глядя на фактический источник Struts, вы увидите, что он просто возвращает экземпляры классов действий назад. и так, два запроса могут попасть в одну и ту же переменную экземпляра, создавая много проблем, если она не синхронизирована правильно.

protected Action processActionCreate(HttpServletRequest request,
    HttpServletResponse response, ActionMapping mapping)
    throws IOException {

    // Acquire the Action instance we will be using (if there is one)
    String className = mapping.getType();

    Action instance;

    synchronized (actions) {
        // Return any existing Action instance of this class
        instance = (Action) actions.get(className);

        if (instance != null) {
            return (instance);
        }
   .......
    }
.....
}
...