Incrementos Thread-Safe
Posted on | Diciembre 21, 2008 |
En estos días comencé a leer Java Concurrecy in Practice y ya en las primeras páginas del libro he detectado errores en él código que llevo escrito para el proyecto.
Resulta que por cada mensaje que envío al server debo mandar un consecutivo, para ello tenía un static long, que sencilla e ingenuamente incrementaba cada vez que había una petición. Pues bien, esta operación es altamente peligrosa en un entorno de concurrencia, como lo es un servlet, debido a que la operación de incrementar un entero no es una operación atómica, osea que se constituye de 3 pasos:
- Leer el valor del long
- Incrementar el valor
- escribir el nuevo valor
Y evidentemente mientras se está en alguno de esos pasos otro hilo puede comenzar la operación crear una “race condition”, es decir que dos hilos o más compiten por incrementar y escribir el nuevo valor, por desgracia sea quien sea quien gane esa carrera solo habrá un verdadero perdedor: Nuestro sistema.
Por supuesto que se puede usar el synchronized(que es lo que suelo hacer), pero en el libro este leí que entre las bibliotecas de java ya hay una solución empaquetada: los AtomicXXX, en nuestro caso: AtomicLong y su metodo: AtomicLong::incrementAndGet(), el cual hace que la operacion de incrementar sí sea atómica, y por tanto Thread-safe.
Comments
Leave a Reply