Actividades

Actividad 7: Sistema de retiro bancario

En esta actividad, simularás un sistema de retiro bancario donde múltiples clientes (hilos) intentan retirar dinero de una cuenta compartida. Deberás implementar la sincronización adecuada para evitar condiciones de carrera y garantizar que el saldo de la cuenta se actualice correctamente.

Descripción de la Actividad

Se desea simular un sistema de retiro bancario donde múltiples cajeros automáticos (threads) realizan retiros de una misma cuenta bancaria.

Problema:

Si varios cajeros descuentan dinero al mismo tiempo, el saldo puede volverse incorrecto debido a condiciones de carrera.

El sistema debe garantizar que solo un hilo modifique el saldo a la vez utilizando semáforos.

Código base de ejemplo

public class BankAccount {

    private int balance = 1000;

    public void withdraw(int amount) {
        if (balance >= amount) {

            IO.println(Thread.currentThread().getName() +
                    " esta retirando: " + amount);

            balance = balance - amount;

            IO.println("Saldo restante: " + balance);
        }
        else {
            IO.println("Fondos insuficientes para " + Thread.currentThread().getName() +
                    " al intentar retirar: " + amount);
        }
    }
}
public class ATMThread extends Thread {

    private BankAccount account;

    public ATMThread(BankAccount account, String name) {
        super(name);
        this.account = account;
    }

    public void run() {
        for(int i = 0; i < 3; i++) {
            account.withdraw(200);
        }
    }
}
void main() {

    BankAccount account = new BankAccount();

    ATMThread atm1 = new ATMThread(account, "ATM 1");
    ATMThread atm2 = new ATMThread(account, "ATM 2");

    atm1.start();
    atm2.start();
}

Tareas a Realizar

  1. Analiza el código base y explica por qué puede haber problemas de concurrencia al ejecutar los hilos ATMThread sin sincronización.
  2. Implementa un mecanismo de sincronización utilizando semáforos para asegurar que solo un hilo pueda acceder al método withdraw a la vez.
  3. Modifica el código para que cada hilo intente retirar una cantidad aleatoria entre 100 y 300 en cada iteración, y ejecuta el programa varias veces para observar cómo se comporta el sistema con la sincronización implementada.
  4. Agrega un contador de intentos de retiro exitosos y fallidos para cada hilo, e imprímelo al finalizar la ejecución de cada hilo.
  5. Responde a las siguientes preguntas:
    • ¿Qué sucede si no se utiliza un mecanismo de sincronización en este escenario?
    • ¿Cómo garantiza el uso de semáforos que el saldo de la cuenta se actualice correctamente?
    • ¿Qué otras alternativas de sincronización podrían haberse utilizado en este caso y por qué?
  6. Para realizar de una forma más realista, agrega un tiempo de espera aleatorio entre los retiros para simular el tiempo que tarda cada cliente en realizar su transacción.
  7. Para la implementación es necesario crear una interfaz gráfica que muestre el saldo de la cuenta en tiempo real, así como los intentos de retiro exitosos y fallidos de cada hilo.
  8. Recuerda implementar la biblioteca de componentes que has utilizado en actividades anteriores para crear la interfaz gráfica y extenderla para mostrar la información requerida con nuevos componentes y delegators necesarios.
Los componentes recomendados para la interfaz gráfica son:
  • Label para mostrar el saldo de la cuenta.
  • List o TextArea para mostrar los intentos de retiro exitosos y fallidos de cada hilo.
  • Button para iniciar la simulación de los retiros.
  • Timer para actualizar el saldo de la cuenta en tiempo real.
Recuerda que deberás comentar cada parte de tu código para explicar su funcionamiento, especialmente la parte relacionada con la sincronización utilizando semáforos. Toma en cuenta que los bloques JavaDoc son una excelente manera de documentar tus métodos y clases, proporcionando una descripción clara de su propósito y funcionamiento.

Recomendaciones

  • Asegúrate de manejar correctamente las excepciones que puedan surgir al trabajar con semáforos.
  • Prueba tu implementación con diferentes cantidades de hilos y retiros para verificar que el sistema se comporta de manera correcta y que el saldo de la cuenta se actualiza adecuadamente sin condiciones de carrera.

Entrega

Para la entrega deberás subir tu código completo con la implementación de la sincronización utilizando semáforos, así como un único documento PDF que contenga:

  • Portada con nombre de los integrantes del equipo, nombre de la actividad y fecha de entrega.
  • Respuestas a las preguntas planteadas en la sección de tareas.
  • Capturas de pantalla que evidencien la correcta ejecución del programa, mostrando los intentos de retiro exitosos y fallidos, así como el saldo actualizado de la cuenta después de cada retiro.
  • Reflexión final sobre la importancia de la sincronización en sistemas concurrentes y cómo el uso de semáforos contribuye a evitar problemas de concurrencia en este tipo de escenarios.

Lista de cotejo para evaluación

CriterioPuntaje
Utiliza correctamente acquire() y release()10 puntos
Implementación de la interfaz gráfica para mostrar el saldo y los intentos de retiro10 puntos
Respuestas claras y completas a las preguntas planteadas20 puntos
Capturas de pantalla que evidencien la correcta ejecución del programa20 puntos
Reflexión final sobre la importancia de la sincronización20 puntos
Documentación y comentarios en el código10 puntos
Presentación en clase explicando la implementación y resultados obtenidos10 puntos

Para efectos de la entrega, se realizará una presentación en clase donde cada equipo explicará su implementación, las decisiones tomadas y los resultados obtenidos. Se evaluará la claridad de la explicación, la calidad del código y la capacidad de cada uno de los miembros del equipo para responder preguntas relacionadas con la actividad.

Recuerda que la presentación debe ser clara y concisa, enfocándose en los aspectos más relevantes de la implementación y los resultados obtenidos.

Es importante recalcar que la presentación es una parte fundamental de la evaluación y requisito para la entrega de la actividad, ya que en caso de no presentarse, el equipo no podrá ser evaluado y, por lo tanto, se considerará como no entregada la actividad, independientemente de la calidad del código o la documentación presentada.

Copyright Jesús Aurelio Castro Magaña © 2026