Java JEE6@ApplicationScoped bean和并发
我需要编写一个bean,作为访问次数的计数器 我正在考虑将@ApplicationScoped bean与原子整数一起使用Java JEE6@ApplicationScoped bean和并发,java,jakarta-ee,concurrency,cdi,Java,Jakarta Ee,Concurrency,Cdi,我需要编写一个bean,作为访问次数的计数器 我正在考虑将@ApplicationScoped bean与原子整数一起使用 @ApplicationScoped class VisitsCounter { private AtomicInteger counter; @PostConstruct public void construct() { counter = new AtomicInteger(0); } public int
@ApplicationScoped
class VisitsCounter {
private AtomicInteger counter;
@PostConstruct
public void construct() {
counter = new AtomicInteger(0);
}
public int visited() {
return counter.incrementAndGet();
}
}
我的问题是:当同时考虑多个请求时可以吗?或者我需要使用@concurrentymanagement和@Lock注释吗?我想原子弹应该会起作用,但我不确定
当我将线程安全集合作为一个字段时,是否也同样适用?比如说我有
@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只是说明注入对象的基数,即指示注入引擎只创建bean的一个实例,并在所有应用程序中使用它。它不会在EJB中转换bean,也不会强制执行任何并发约束 因此,尽管由于AtomicInteger和synchronized list,示例中的操作本质上是线程安全的,但通常情况下并非如此 一般来说,您可以: 如您所做的那样,通过标准并发原语手动同步列表访问 或者使用javax.ejb.Singleton注释,它指示应用程序服务器管理并发性。这将在EJB中转换bean,并在默认情况下强制@ConcurrencyManagementConcurrencyManagementType.CONTAINER和@LockLockType.WRITE
顺便说一句,@concurrentymanagement和@Lock仅在单例会话bean上可用。实现后,我看不到任何并发问题。很好。我在想,如果我将@ApplicationScoped bean注入@Stateful EJB,会发生什么情况,似乎您可能会遇到问题,因为从EJB的两个实例可以修改相同的数据。字段计数器、值是否保证可见?毕竟,它们是由不同的线程访问的,没有任何并发机制。