Por: Guido J. Granobles. En el ejemplo que vimos en el post anterior donde se intenta hacer transferencia de dinero entre dos cajas, debemos notar que este es un proceso Atómico con 2 transacciones un debito en una caja y un crédito en la otra donde ambas transacciones o ninguna debe llevarse a cabo. Por lo tanto un hilo debería poder asegurar ambos objetos (las 2 cajas) antes de empezar las operaciones. Para ello la clase Caja tendrá un miembro lock que será una instancia de la clase ReentrantLock (línea 10 del listado de codigo abajo), el método transfer (línea 37) de la clase operaCaja hace uso de lock para asegurar el objeto Caja (líneas 48 y 51), si logra asegurar ambas cajas tanto origen como destino (línea 63), entonces procede a debitar y acreditar saldos en caso contrario sale del método retornando un false. El hilo al verificar que no se llevo a cabo la transacción suspenderá su ejecución con un Sleep por 100 milésimas de segundo (líneas 106 y 126) y luego intenta de nuevo la transacción, este proceso se repite hasta que la transacción sea exitosa. Pero bueno bien sabido es que un buen trozo de código vale más que mil palabras, veamos el ejemplo:
|
|||||||
| Comentarios | 0 | Visitas: 1390 |
Por Guido J. Granobles. Es conocido por muchos que el uso de la palabra clave synchronized ya sea para el establecimiento de métodos o bloques de código sincronizado afecta el desempeño óptimo de las aplicaciones en cuanto a velocidad de procesamiento se refiere. Aunque el uso abusivo de este tipo de bloques de código se ha condenado desde sus inicios cabe decir que las constantes mejoras de la JVM a través de los años hace que la comparación entre el porcentaje de desempeño afectado VS los grandes beneficios a la hora de resolver problemas de concurrencia, inclinan la balanza hacia este ultimo. El principal problema asociado con el uso excesivo de los bloques de código sincronizado está en que a medida que se incrementan este tipo de métodos o bloques en una aplicación, mayor es la posibilidad de que en algún punto del programa durante la ejecución del mismo se presenten los conocidos DeadLocks que hacen que la aplicación entre en un loop infinito obligando a que sea reiniciada.
En concreto un DeadLock ocurre cuando como mínimo dos hilos intentan simultáneamente asegurar un objeto que el hilo contrario ya tiene. Para ser más claro expondré un ejemplo, el hilo A obtiene el Lock del objeto1 (o asegura el objeto1) mientras el hilo B obtiene el Lock del objeto2, seguidamente el hilo A intenta obtener el Lock del objeto2 antes de liberar el Lock del objeto1, al mismo tiempo el hilo B intenta obtener el Lock del objeto1 antes de liberar el Lock del objeto2, lo que tenemos aquí es que el hilo A esperara hasta que el hilo B libere el Lock del objeto2 mientras el Hilo B está esperando a que el hilo A libere el Lock del objeto1 y así se quedaran esperando el uno al otro hasta el día del juicio final o hasta que alguien reinicie la aplicación o la maquina. Veamos el ejemplo en código:
|
|||||||
| Comentarios | 0 | Visitas: 885 |
Por: Guido J. Granobles. En ocasiones necesitamos que un programa Java actue como un servicio que se inicia bien sea de manera manual o cada vez que nuestro OS arranca. Estos servicios se ejecutan en background y estan constantemente a la espera de eventos o ejecutando tareas especificas en intervalos de periodos definidos, a estos servicios se les conoce tambien como demonios o daemons en la lengua inglesa. A diferencia de una aplicacion normal los demonios son controlados por el OS en su arranque y en su finalizacion, permitiendo completar tareas de liberacion de recusros en cada finalizacion del servicio o cuando la maquina ha recibido una orden de apagado. Para crear una aplicacion que se ejecute como un demonio debemos implementar la interface Daemon usando el paquete que nos provee Apache, la cual pueden encontrar en http://commons.apache.org/daemon.com La interface contiene los siguientes metodos que debemos implementar: |
|||||
| Comentarios | 1 | Visitas: 1494 |