Переменная класса в EJB 3 потокобезопасна?

#java #thread-safety #ejb

#java #потокобезопасность #ejb

Вопрос:

В сервлете, потому что это одноэлементный, за исключением реализации SingleThreadModel . Обратитесь к этой статье https://www.fortify.com/vulncat/en/vulncat/java/singleton_member_field_race_condition.html

Но в EJB 3 я не могу найти аналогичный документ. И потому, что контейнер создаст пул для обработки EJBS. Я думаю, что переменная класса должна быть безопасной, это правильно?

Например, classVar1 это переменная класса, я инициализирую ее в конструкторе и использую позже. В сервлете может возникнуть проблема, но в EJB 3 все должно быть в порядке, верно?

 @Stateles
public class HelloBean implements Hello {

    ObjectXXX classVar1;

    public HelloBean() {
        ObjectXXX classVar1 = new ObjectXXX();
    }

    public String doHello(String message) {
        return message   classVar1.method1();
    }
}
  

И еще один вопрос заключается в том, что ресурс (т. Е. EntityManager в JPA), введенный в EJB, должен быть потокобезопасным?

Ответ №1:

Контейнер должен пропускать только 1 поток в конкретном экземпляре EJB, поэтому: каждый метод может быть выполнен только одним потоком, и ваша переменная «безопасна» (поскольку вы инициализируете ее в конструкторе или @PostConstruct методе).

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

EntityManager, как и каждое поле экземпляра в EJB, потокобезопасен.

Однако сам EntityManager не потокобезопасен и не может использоваться в среде, где более 1 потока могут получить к нему доступ (т. Е. в сервлете). EntityManagerFactory вместо этого следует использовать в таких случаях.

Комментарии:

1. поправьте меня, если я ошибаюсь, EntityManager, введенный в ejb сервером приложений, потокобезопасен, на самом деле это прокси. однако это не выполняется для компонента CDI через @PersistenceContext

2. Да, контейнер использует прокси-сервер EntityManager, но я не совсем понимаю «компонент CDI через @PersistenceContext' «. Вы имеете в виду внедрение компонента CDI в EJB с помощью @Inject или @PersistenceContext EntityManager, введенного в компонент CDI?

3. @Depeng ты немного ошибаешься. Диспетчер объектов НЕ гарантируется потокобезопасностью. Это может быть в конкретной реализации, но это не обязательно. EJB без состояния или с сохранением состояния — это то, что делает доступ к внедренному менеджеру объектов безопасным, поскольку эти два сами по себе потокобезопасны.