viernes, 18 de abril de 2014

SINCRONIZACIÓN - II

Existen dos niveles de bloqueo de un recurso. El primero es a nivel de objetos. mientras que el segundo es a nivel de clases. El primero se consigue declarando todos los métodos de una clase como synchronized. Cuando se ejecuta un método synchronized sobre un objeto concreto, el sistema bloquea dicho objeto, de fonna que si otro thread intenta ejecutar algún método sincronizado de ese objeto, este segundo método se mantendrá a la espera hasta que finalice el anterior (y desbloquee por lo tanto el objeto). 
Si existen varios objetos de una misma clase, como los bloqueos se producen a nivel de objeto, es posible tener distintos threads ejecutando métodos sobre diversos objetos de una misma clase. El bloqueo de recursos a nivel de clases se corresponde con los métodos de clase o static. y por lo tanto con las variables de clase o static. Si lo que se desea es conseguir que un método bloquee simultáneamente una clase entera, es decir todos los objetos creados de una clase, es necesario declarar este método como synchronized static. Durante la ejecución de un método declarado de esta segunda fonna ningún método sincronizado tendrá acceso a ningún objeto de la clase bloqueada. 
La sincronización puede ser problemática y generar errores. Un thread podría bloquear mi determinado recurso de fonna indefinida, impidiendo que el resto de threads accedieran al mismo. Para evitar esto último, habrá que utilizar la sincronización sólo donde sea estrictamente necesario. Es necesario tener presente que si dentro un método sincronizado se utiliza el método sleepf) de la clase Thread. el objeto bloqueado permanecerá en ese estado durante el tiempo indicado en el argumento de dicho método. Esto implica que otros threads no podrán acceder a ese objeto durante ese tiempo, aunque en realidad no exista peligro de simultaneidad ya que durante ese tiempo el thread que mantiene bloqueado el objeto no realizará cambios. Para evitarlo es conveniente sustituir sleepf) por el método yvaitQ de la clase java.lang.Object heredado automáticamente por todas las clases. 
Cuando se llama al método waitQ (siempre debe hacerse desde un método o bloque synchronized) se libera el bloqueo del objeto y por lo tanto es posible continuar utilizando ese objeto a través de métodos sincronizados. El método waitQ detiene el thread hasta que se llame al método notifyf) o notifyAllf) del objeto, o finalice el tiempo indicado como argumento del método waitQ. El método un Objeto.notifyf) lanza una señal indicando al sistema que puede activar uno de los threads que se encuentren bloqueados esperando para acceder al objeto u ti Objeto. El método notifyAllf) lanza una señal a todos los threads que están esperando la liberación del objeto

No hay comentarios:

Publicar un comentario