Me pregunto ¿hay gran diferencia en el uso de ReentrantLock
y synchronized (object)
.
Las principales diferencias son:
Con synchronized
el bloqueo/desbloqueo está ligado a la estructura de bloques de su código fuente. Un bloqueo de synchronized
se liberará cuando salga del bloque, sin importar cómo lo haga. Por ejemplo, se liberará si el bloque termina debido a una excepción inesperada.
Con bloqueo explícito este no es el caso, por lo que puede adquirir ReentrantLock
(o cualquier otro Lock
) en un método y liberarlo en otro. Pero la otra cara es que debe recuerde liberar explícitamente el Lock
en el momento/lugar apropiado. Si no lo haces, terminarás con un bloqueo atascado y (tal vez) puntos muertos. En resumen, ReentrantLock
es más complicado y potencialmente más propenso a errores.
El bloqueo primitivo que obtiene con synchronized
funciona con Object.wait()
y Object.notify()
. Lock
s no.
A ReentrantLock
puede crearse para ser "regular", lo que significa que los hilos que están esperando adquirir un bloqueo determinado adquirirán el bloqueo en orden fifo. Los bloqueos primitivos no son justos.
La API ReentrantLock
tiene métodos que se pueden utilizar para comprobar si el bloqueo está en uso, conocer la longitud de la cola de bloqueo, intentar adquirir el bloqueo sin bloquear, y varias otras cosas. Ninguna de esta funcionalidad está disponible para bloqueos primitivos.
Por eso se llama un bloqueo de reentrada? para permitir llamadas recursivas desde el mismo hilo?
Un bloqueo de reentrada permite que un hilo que está sosteniendo un bloqueo lo vuelva a adquirir. Una de las formas en que esto podría suceder es a través de la recursión, pero también hay otras.
Para el registro, synchronized
bloqueos son reentrantes, por lo que no tiene que preocuparse por la recursión, u otros escenarios donde un hilo podría adquirir un bloqueo que ya tiene.
@skaffman - Esa pregunta no cubre el tema "reentrante". –