gra*_*hez 23 java concurrency java-ee cdi
我需要编写一个bean来充当访问它的次数的计数器.
我正在考虑像这样使用@ApplicationScopedbeanAtomicInteger
@ApplicationScoped
class VisitsCounter {
private AtomicInteger counter;
@PostConstruct
public void construct() {
counter = new AtomicInteger(0);
}
public int visited() {
return counter.incrementAndGet();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:在同时考虑多个请求时可以吗?或者我需要玩@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);
}
}
Run Code Online (Sandbox Code Playgroud)
这些操作真的是线程安全的吗?
据说当修改bean的状态时应该使用并发注释和锁,但是如果我的列表已经处理了线程安全怎么办?
Car*_*ini 37
在CDI中,您没有并发管理,因此@ApplicationScoped只需说明注入对象的基数(即指示注入引擎只创建一个bean实例并在所有应用程序中使用它).它不会在EJB中转换bean,也不会强制执行任何并发约束.
因此,虽然示例中的操作本质上是线程安全的,但由于AtomicInteger和同步列表,通常情况并非如此.
一般来说,你可以:
通过标准并发原语手动同步列表访问(如您所做)
或使用javax.ejb.Singleton注释,指示应用程序服务器管理并发.这会在EJB中转换您的bean,默认情况下强制执行@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)和@Lock(LockType.WRITE).
顺便说一句,@ConcurrencyManagement并且 @Lock仅在单例会话bean上可用.
| 归档时间: |
|
| 查看次数: |
10240 次 |
| 最近记录: |