java - "non-managed"实用程序类的并发访问和扩展

标签 java jakarta-ee concurrency ejb cdi

如果我有一个有状态类,需要一个类似实用程序的无状态类来对其执行操作。这些有状态类保存在容器(有状态)类的列表中。这就是我用普通 Java 所做的事情:

class Container {
    List<Stateful> sfList;
}

class Stateful {

    List<String> list;

    void someMethod() {
        list.add("SF");
        Stateless.foo(this);
}

class Stateless {
    public static void foo(Stateful sf) {
        sf.getList().add("SL");
    }
}

main内部,这是过程:

Stateful sf = new Stateful();
sfList.add(sf);
sf.someMethod();

现在使用 JavaEE CDI 我会这样做:

class StatefulBean {

    List<String> list;

    @Inject
    StatelessBean slsb;

    void someMethod() {
        list.add("SF");
        slsb.add(this);
}

@Stateless
class StatelessBean {
    public void add(StatefulBean sfsb) {
        sfsb.add("SL");
    }
}

在这种情况下,所有 StatefulBean 都可以访问 StatelessBean 的共享池,没有并发问题,并且它将根据请求正确扩展。

但是,由于 Stateful 不是托管 bean,我无法注入(inject)它,因此我使用了实用程序类。另外,我使用构造函数创建 Stateful ,因此我无法将无状态 bean 注入(inject)其中(我将使用它获得 NPE)。

我的问题是:

  • 无状态注入(inject)方法(只要可行)和实用程序类方法之间是否存在并发性和可扩展性差异?
  • 如何使 EE 注入(inject)方法发挥作用?

最佳答案

Are there concurrency and scalabilty differences between the stateless injection approach (provided it would work) and the utility class approach?

是的,有,主要是因为管理层的流失。您实例化的方式 Stateful每次调用该方法时,都不涉及池化。这将导致您创建比您可能需要的更多的实例。

另一个损失是在可扩展性方面。容器将在分布式环境中管理有状态 bean 的钝化和激活,而手动方法将确保您管理自己的激活和钝化。

Since Stateful is not a managed bean..

不正确。根据CDI Spec ,任何满足列出的条件的 java 类(在您的情况下,是默认的无参数构造函数)都是托管 bean。这意味着您可以@Inject StatelessBean进入Stateless容器会答应的。要允许此级别的管理,您需要设置 bean-discovery-mode=all在您的 beans.xml 中。

即使使用(显然不必要的)循环引用,正常的 Java 并发规则也适用:只要您正在操作的状态不是静态的或在静态类中,您就是线程安全的。对该静态方法的每个线程调用仍然在单独的堆栈上运行,因此没有问题。

How can I make the EE injection approach work? If you need on-demand instantiation of Stateless(or any other bean really), use the CDI Instance to programmatically obtain a managed instance of any class you want. You can now add something like this to Container:

@Inject @Dependent Instance<Stateful> stateful;

    @PostConstruct
     public void createStateless(){
         //instantiate sfList;
         sfList.add(stateful.get()); //execute as many times as you need
     }

关于java - "non-managed"实用程序类的并发访问和扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45645099/

相关文章:

java - readLine 用于读取多行而不循环?

java - 如何检查 ConcurrentLinkedQueue 的 size() 或 isEmpty()

c++ - 项目中共享模型的多线程同步

java - 如何使用 JPA 和 Hibernate 加入两个不相关的实体

java - 使用 HTML 文本更改禁用 Java 按钮的文本颜色

java - 在 iterator.remove 上抛出 ConcurrentModificationException

jakarta-ee - JPA 实体静态记录器

java - 无法使用 updatetool 安装 javaee7 教程的教程内容

java - Spring @Async 和同步

java - 构造函数中的匿名比较器使用强制转换为 Comparable