3 de junio de 2021

Ejercicios selectos (excepciones).

  1. Con base en lo descrito en la entrada Excepciones, considere el Ejemplo DivisionConManejoExepcion2 y compárese en el ejemplo de dicha entrada (Ejemplo DivisionConManejoExepcion). La equivalencia lógica y funcional es la misma, note que la diferencia radica en la cláusula finally del ejemplo en cuestión (líneas 41-44). Asegúrese de comprender las diferencias así como su equivalencia.
  2. Escriba una clase de prueba que permita probar el funcionamiento de la clase ListOfNumbers.
  3. En las versiones de Java 7 y posteriores, un bloque catch puede manejar más de un tipo de excepción. Dicha característica pretende reducir la duplicidad de código y tener demasiada extensión en las cláusulas de tipo catch. En este sentido, considere el Ejemplo ListOfNumbers2 que es la versión actualizada del Ejemplo ListOfNumbers visto en la entrada Atrapando y manejando excepciones. Asegúrese de entender su equivalencia antes de continuar.
  4. Tomando en consideración lo descrito en la entrada Especificación de excepciones lanzadas por un método, modifique el Ejemplo ListOfNumbers2 para que el método writeList( ) no maneje la excepción, sino que indique que la puede lanzar. Así mismo, deberá modificar de manera apropiada lo realizado en el Ejercicio 2 (ahora la clase de prueba tendrá que hacer el manejo correspondiente de la excepción) para que el programa siga funcionando.
  5. En la entrada Excepciones se trabajó con el Ejemplo DivisionConManejoExepcion, y en el Ejercicio 1 con una versión alternativa (Ejemplo DivisionConManejoExepcion2). Considere ahora el Ejemplo DivisionConManejoExcepcion3 y asegúrese de comprender las diferencias así como las equivalencias con los ejemplos citados. Note que la única diferencia de este último con respecto de la versión anterior es la cláusula throws ArithmeticException (línea 17). En la entrada Especificación de excepciones lanzadas por un método puede consultar los detalles de dicha cláusula.
  6. Considere una ecuación cuadrática de la forma ax^2 + bx + c. Escriba un programa que permita leer los coeficientes reales de una ecuación de este tipo y obtenga las raíces reales de la misma. Para ello:
    • Si el coeficiente a es cero, deberá generar tanto la excepción como el manejo correspondiente de la misma; es decir, su programa deberá reportar el problema (no es una ecuación cuadrática) y continuar.
    • Detectar si los coeficientes no son números.
    • Si las raíces de la ecuación no son números reales, deberá también reportar dicha situación como una excepción y realizar el manejo correspondiente (preguntar al usuario si desea continuar o no).
  7. Considere el Ejemplo Excepciones el cual contiene comentarios respecto a secciones de código que serían inalcanzables. Compruebe que así sea, para ello, puede agregar una sentencia simple en donde sea pertinente como por ejemplo System.out.println("¿Qué pasará?"); y analice ¿qué sucede?, ¿compila?, ¿se ejecuta?
  8. Para el Ejemplo Excepciones3, ¿que piensa que ocurrirá si se elimina alguna de las cláusulas throws Exception (líneas 10, 16, 22 y 28)? Determine primero su respuesta, y posteriormente compruébese con la experimentación.
  9. Con base en lo expuesto en el ejercicio anterior, ¿qué piensa que sucederá si en lugar de una excepción verificada (checked exception) se utiliza una excepción no verificada (uncheked/runtime exception)? Determine y realice el experimento correspondiente.
  10. Con base en lo expuesto en Lanzado y encadenamiento y en los dos ejercicios anteriores, construya un programa que, como en el Ejemplo Excepciones3 se relance una excepción, con la diferencia de que ahora, en cada método, se deberá atrapar la excepción anterior y encadenarla con una nueva creada en ese método, para relanzar esta nueva excepción y que a su vez sea atrapada y encadenada con una nueva en el método siguiente. Revise nuevamente el Ejemplo Excepciones2 para ver cómo crear un excepción encadenada (compuesta).
  11. A partir de la versión 7 de Java, se incorporó la sentencia try-con-recursos (try-with-resources), la cual permite declarar uno o más recursos dentro de la cláusula. Dichos recursos son objetos que deben ser cerrados cuando el programa que los utiliza ha terminado con ellos. El Ejemplo ListOfNumbers3 es una muestra de cómo funciona dicha cláusula, pero se invita al lector a documentarse más al respecto.

 

2 de junio de 2021

Interbloqueo.

     Al hablar de concurrencia, existe un concepto que se utiliza con frecuencia en el argot de Java: liveness (vivacidad), mismo que podría definirse como la capacidad de una aplicación concurrente de ejecutarse oportunamente. Asociado a este concepto vienen otros estrechamente relacionados: deadlock (interbloqueo) y starvation (inanición).

    El interbloqueo describe una situación en la que dos o más hilos están bloqueados, esperando que uno habilite al otro para su continuación sin que esto nunca ocurra. Considere el siguiente ejemplo:

Alfonso y Gastón son amigos y apasionados fervientes de las estrictas costumbres de cortesía. Una de estas reglas inquebrantables es aquella que dicta que cuando una persona se inclina en afectuoso saludo de reverencia a un amigo, ésta debe permanecer inclinada hasta que el amigo tenga la oportunidad de regresar el saludo con otra reverencia.

    Desafortunadamente para este par de amigos, esta regla no toma en cuenta la posibilidad de que ambas personas pudieran iniciar la reverencia al otro simultáneamente.

    El Ejemplo Interbloqueo modela la situación planteada líneas antes. Cuando este ejemplo se ejecuta, lo más seguro es que ambos hilos se bloqueen cuando intenten invocar al método "regresaReverencia". Asegúrese el lector de comprobar en este momento dicha situación.

    El bloqueo mutuo o interbloqueo nunca terminará debido a que cada hilo está esperando que el otro salga del método "reverencia". Ambos hilos se quedarán esperando por siempre una situación que sólo el otro debe causar pero que nunca ocurrirá.

    En la entrada de Ejercicios se proponen dos ejercicios (10 y 11) relacionados con este ejemplo. Se recomienda ampliamente revisar todos los temas relacionados con hilos y la comprensión del ejemplo aquí presentado antes de intentarlos.

    Finalmente, se comentan dos aspectos estrechamente relacionados con lo anterior:

  1. Según la documentación oficial de Java, la inanición (starvation) describe una situación en la que un hilo no puede obtener un acceso regular a los recursos compartidos y en consecuencia no puede progresar.
  2. Por otro lado, existe una situación similar pero diferente al interbloqueo denominada livelock. La diferencia es sutil pero importante: en un livelock los hilos no están bloqueados sino en ejecución pero estorbándose sin poder continuar. La situación es comparable con la de dos personas tratando de pasar por en pasillo estrecho: Alfonso se mueve a la derecha para permitir que Gastón pase, al tiempo que Gastón se mueve a su izquierda para permitir a Alfonso que pase; si esta situación se repite en el sentido inverso, ambos se seguirán bloqueando sin poder pasar y en consecuencia, sin poder avanzar.