java - tipos - JEE6 @ApplicationScoped bean y concurrencia
managed bean scope view</ managed bean scope (1)
En CDI no tiene gestión de concurrencia, por lo que @ApplicationScoped
simplemente establece la cardinalidad del objeto inyectado (es decir, le indica al motor de inyección que cree solo una instancia de su bean y la use en toda la aplicación). No transforma su bean en un EJB, y no impone ninguna restricción de concurrencia.
Así, mientras que las operaciones en los ejemplos son inherentemente seguras para subprocesos, gracias a AtomicInteger
y la lista sincronizada, lo mismo no es cierto en general.
En general puedes:
sincronice manualmente los accesos de la lista a través de los primitivos de concurrencia estándar (como lo ha hecho)
o use la anotación
javax.ejb.Singleton
, que le indica al servidor de aplicaciones que administre la concurrencia. Esto transforma su bean en un EJB y, de forma predeterminada, aplica@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
y@Lock(LockType.WRITE)
.
Por cierto, @ConcurrencyManagement
y @Lock
solo están disponibles en beans de sesión singleton.
Necesito escribir un bean que actúe como un contador de cuántas veces se accedió.
Estoy pensando en usar @ApplicationScoped
bean con AtomicInteger
así
@ApplicationScoped
class VisitsCounter {
private AtomicInteger counter;
@PostConstruct
public void construct() {
counter = new AtomicInteger(0);
}
public int visited() {
return counter.incrementAndGet();
}
}
Mi pregunta es: ¿está bien si se consideran varias solicitudes al mismo tiempo? ¿O necesito jugar con @ConcurrencyManagement
y @Lock
anotaciones? Supongo que Atomic*
debería hacer el truco pero no estoy seguro.
¿También ocurre lo mismo cuando tengo subprocesos seguros como campos? Por ejemplo decir que tengo
@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);
}
}
¿Son las operaciones realmente seguras para subprocesos?
Se dice que se deben usar anotaciones y bloqueos de concurrencia cuando hay una modificación del estado del bean, pero ¿qué pasa si mi lista ya se encarga de la seguridad de los hilos?