java - JEE6 @ApplicationScoped bean 和并发

标签 java jakarta-ee concurrency cdi

我需要编写一个 bean 来作为它被访问次数的计数器。

我正在考虑将 @ApplicationScoped bean 与 AtomicInteger 一起使用

@ApplicationScoped
class VisitsCounter {

    private AtomicInteger counter;

    @PostConstruct
    public void construct() {
        counter = new AtomicInteger(0);
    }

    public int visited() {
        return counter.incrementAndGet();
    }
}

我的问题是:同时考虑多个请求时可以吗?还是我需要使用 @ConcurrencyManagement@Lock 注释?我想 Atomic* 应该可以解决问题,但我不确定。

当我将线程安全集合作为字段时,同样适用吗?例如。说我有

@ApplicationScoped
class ValuesHolder {

    private List<String> values;

    @PostConstruct
    public void construct() {
        values = Collections.synchronizedList(new LinkedList<String>());
    }

    public void insert(String value) {
        values.add(value);
    }

    public String remove(String value) {
        return values.remove(value);
    }
}

这些操作真的是线程安全的吗?

据说当bean的状态发生修改时应该使用并发注解和锁,但是如果我的列表已经照顾了线程安全呢?

最佳答案

在 CDI 中,您没有并发管理,因此 @ApplicationScoped 只是说明注入(inject)对象的基数(即指示注入(inject)引擎只创建一个 bean 实例并在所有实例中使用它应用程序)。它不会在 EJB 中转换您的 bean,也不会强制执行任何并发约束。

因此,虽然示例中的操作本质上是线程安全的,但由于 AtomicInteger 和同步列表,通常情况并非如此。

一般来说你可以:

  • 通过标准并发原语手动同步列表访问(正如您所做的那样)

  • 或使用javax.ejb.Singleton注解,指示应用服务器管理并发。这会在 EJB 中转换您的 bean,默认情况下强制执行 @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)@Lock(LockType.WRITE)

顺便说一下,@ConcurrencyManagement@Lock 仅在单例 session bean 上可用。

关于java - JEE6 @ApplicationScoped bean 和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14237499/

相关文章:

java - 如何通过 wicket ajax 行为捕获来自 &lt;input type ="date"> 的事件?

java - 使用 java 的 FIX 协议(protocol)

java - Jersey-Server 响应未能发送字节 []

java - 安装 Java EE 6 SDK

jakarta-ee - JBoss AS 7.1 - 使用 @Schedule 注释运行计划

java - 为什么 java.util.concurrent.ArrayBlockingQueue 在调用 await() 时使用 'while' 循环而不是 'if'?

android - 无法启动接收器 com.parser.Parse BroadcastReceiver : ConcurrentModificationException

JavaFX如何计算打字错误

java - 如何从单独的类调用 Activity 的方法

java - 我需要如何重新实现 JCheckBox