Limitaciones de bloques sincronizados
Limitaciones de los bloques sincronizados y alternativas
Los bloques sincronizados en Java tienen varias limitaciones.
-
Por ejemplo, un bloque sincronizado en Java solo permite que un solo hilo entre a la vez. Sin embargo, ¿qué pasa si dos hilos solo quisieran leer un valor compartido, y no actualizarlo? Eso podría ser seguro de permitir. Como alternativa a un bloque sincronizado, podríamos proteger el código con un
Read / Write Lock
que tiene una semántica de bloqueo más avanzada que un bloque sincronizado. Java en realidad viene con una clase incorporadaReadWriteLock
que podemos usar. -
¿Qué pasa si queremos permitir que N hilos entren en un bloque sincronizado, y no solo uno? Podríamos usar un Semáforo (
Semaphore
) para lograr ese comportamiento. Java, de nuevo, cuenta con una claseSemaphore
incorporada que podemos usar. -
Los bloques sincronizados no garantizan en qué orden se concede acceso al bloque sincronizado a los hilos que esperan para entrar. ¿Qué pasa si necesitamos garantizar que los hilos que intentan entrar en un bloque sincronizado obtengan acceso en la secuencia exacta en la que solicitaron acceso? Necesitamos implementar la equidad (en inglés, fairness) nosotros mismos.
-
¿Qué pasa si solo tenemos un hilo escribiendo en una variable compartida, y otros hilos solo leyendo esa variable? Aquí podríamos ser capaces de usar simplemente una variable
volatile
sin ninguna sincronización alrededor.
Sobrecarga de rendimiento del bloque sincronizado
Hay una pequeña sobrecarga de rendimiento asociada con entrar y salir de un bloque sincronizado en Java. A medida que Java ha evolucionado, esta sobrecarga de rendimiento ha disminuido, pero todavía hay un pequeño precio que pagar.
La sobrecarga de rendimiento de entrar y salir de un bloque sincronizado es principalmente algo de lo que preocuparse si entramos y salimos de un bloque sincronizado muchas veces dentro de un ciclo rápido o algo similar.
Además, debemos tratar de no tener bloques sincronizados más grandes de lo necesario. En otras palabras, sincronizar solo las operaciones que realmente son necesarias sincronizar - para evitar bloquear a otros hilos de ejecutar operaciones que no tienen que ser sincronizadas. Solo las instrucciones absolutamente necesarias en bloques sincronizados. Eso debería aumentar el paralelismo de nuestro código.