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