问题描述
我需要写一个bean作为访问次数的计数器。
I need to write a bean that would act as a counter of how many times it was accessed.
我想使用 @ApplicationScoped
豆类与 AtomicInteger
一样
@ApplicationScoped
class VisitsCounter {
private AtomicInteger counter;
@PostConstruct
public void construct() {
counter = new AtomicInteger(0);
}
public int visited() {
return counter.incrementAndGet();
}
}
我的问题是:与此同时?或者我需要使用 @ConcurrencyManagement
和 @Lock
注释吗?我想, Atomic *
应该做的伎俩,但我不知道。
My question is: is it ok when considering multiple requests at the same time? Or do i need to play with @ConcurrencyManagement
and @Lock
annotations? I suppose that Atomic*
should do the trick but I'm not sure.
我有线程安全集合作为字段?例如。说我有
Also does the same applies when I have thread safe collections as a fields? E.g. say I have
@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);
}
}
是真正线程安全的操作吗?
are the operations really thread-safe?
据说在修改bean的状态时应该使用并发注释和锁,但是如果我的列表已经处理了线程安全的话, p>
It is said that concurrency annotations and locks should be used when there is modification of state of the bean, but what if my list already takes care of thread safety?
推荐答案
在CDI中没有并发管理,所以 @ApplicationScoped
表示注入对象的基数(即指示注入引擎仅创建一个bean的实例,并在所有应用程序中使用它)。它不会在EJB中转换您的bean,并且不会强制执行任何并发性约束。
In CDI you don't have concurrency management, so @ApplicationScoped
simply states the cardinality of the injected object (i.e. instructs the injection engine to create only one instance of your bean and use it across all the application). It does not transform your bean in an EJB, and does not enforce any concurrency constraint.
因此,虽然示例中的操作本质上是线程安全的,由于 AtomicInteger
So, while the operations in the examples are inherently thread safe, thanks to the AtomicInteger
and the synchronized list, the same is not true in general.
在一般情况下,您可以:
In the general you can:
-
手动同步通过标准并发原语(如您所做)的列表访问
manually synchronize the list accesses through the standard concurrency primitives (as you have done)
或使用 javax.ejb .Singleton
注释,指示应用程序服务器管理并发。这会在EJB中转换你的bean,并且默认强制 @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
和 @Lock(LockType.WRITE)
。
or use the javax.ejb.Singleton
annotation, which instructs the application server to manage concurrency. This transforms your bean in an EJB and by default enforces @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
and @Lock(LockType.WRITE)
.
顺便说一下, @ConcurrencyManagement
@Lock
只适用于单例会话bean。
By the way, @ConcurrencyManagement
and @Lock
are only available on singleton session beans.
这篇关于JEE6 @ApplicationScoped bean和并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!