2009-11-17 19 views
8

¿Los ámbitos singleton/sesión de Spring Beans requieren que se sincronice el acceso a todos sus campos? Diga a través de la palabra clave "sincronizada" o usando algunas clases del paquete "java.util.concurrent".Primavera: ámbitos únicos y de sesión y concurrencia

Como ejemplo, ¿este código no es seguro para subprocesos? (Copiar/pased de here):

@Component 
@SessionScoped 
public class ShoppingCart { 
    private List<Product> items = new ArrayList<Product>(); 

    public List<Product> getAllItems() { 
     return items; 
    } 

    public void addItem(Product item) { 
     items.add(item); 
    } 
} 

Respuesta

21

Cuando se utiliza singleton alcance del contenedor primavera, se indica que todas las discusiones que recuperan el grano desde el contenedor utilizarán el misma instancia. Entonces, en este caso, cuando la lista de estado del elemento se comparte y se puede modificar entre los hilos, debería sincronizar el acceso a la lista para proteger su aplicación contra un ConcurrentModificationException.

Sin embargo, la práctica habitual con Spring es crear su aplicación con objetos sin estado, que no tienen un estado que cambiará a lo largo de la vida de la aplicación.

En el caso de session alcance, que podrían ser menos propensos a ver un problema de simultaneidad ya que el frijol sólo será accesible por el usuario actualmente conectado. Sin embargo, es posible (al menos en la web) tener varias solicitudes entrando en la misma sesión, en cuyo caso tendría que tomar las mismas precauciones que si el bean fuera singleton.

Una vez más, la mejor manera de protegerse es tratar de mantener su grano lo más parecido a un estado sin estado. Si tiene un bean que requiere estado, debe considerar usar el alcance prototype, que recupera una nueva instancia del bean del contenedor cada vez.

0

Sólo el usuario para esa sesión puede acceder a esta clase, pero ArrayList no es seguro para subprocesos, como se ve en esta discusión: http://forums.sun.com/thread.jspa?threadID=5355402

Usted necesita asegurarse de que su clase es totalmente segura para subprocesos, ya que SessionScoped se asegurará de que solo la use cada sesión, por lo que una sesión no podrá acceder a ella.

Es posible que desee ver en los comentarios en esta discusión para más información: http://wheelersoftware.com/articles/spring-session-scoped-beans.html

-4

Básicamente para cada usuario que inicia una sesión, se creará un nuevo ShoppingCart y se establecerá el alcance para esa sesión por ese usuario.

Tu clase es segura para subprocesos. La inicialización

private List<Product> items = new ArrayList<Product>(); 

es una inicialización thread-safe y

addItem(Product item) es una operación atómica y también es por lo tanto el hilo de seguridad.

+0

Si alguien llama a getItems() y comienza a iterar sobre él, mientras que al mismo tiempo otro subproceso tiene un addItem(), se eliminará una ConcurrentModificationException. Consulte http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html para obtener notas sobre lo que debe sincronizarse para la seguridad de subprocesos con ArrayList. –

+0

La clase no es segura para subprocesos porque la colección de 'elementos' no se publica con seguridad; items.add() no proporciona ninguna garantía de que su efecto sea visible para el hilo sobre el actual y no sea atómico. –

+0

Hmmm Tenía la impresión de que el hecho de que la clase también sea 'SessionScoped' y solo pueda ser actuada por un único actor dentro del contenedor Spring garantizaría la seguridad del hilo de la clase. –

Cuestiones relacionadas