#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 без состояния или с сохранением состояния — это то, что делает доступ к внедренному менеджеру объектов безопасным, поскольку эти два сами по себе потокобезопасны.