Práctica final del módulo PSP (Programación de Servicios y Procesos) del ciclo DAM.
Aplicación de escritorio en JavaFX que simula la venta de entradas de un partido de fútbol: cada aficionado es un hilo independiente que hace cola en las taquillas (controladas por un semáforo) e intenta comprar su entrada. La interfaz muestra en tiempo real el progreso de la simulación, la recaudación final y la lista de espera de los fans que se quedaron sin entrada.
- Se configura el partido desde el formulario: nombre, número de asientos, precio de la entrada, número de fans a simular y número de taquillas.
- Al iniciar la simulación se lanza un hilo por cada fan. Cada fan:
- Llega a la taquilla y espera su turno en la cola.
- Cuando le toca, intenta comprar una entrada (con un tiempo de compra aleatorio de 1–3 segundos).
- Si el aforo se ha agotado, pasa a la lista de espera.
- Al terminar todos los hilos se muestra el resumen con la recaudación total y se habilita el botón para ver la lista de espera en una ventana modal.
- El botón de reinicio deja la aplicación lista para una nueva simulación.
El foco de la práctica es la concurrencia en Java:
- Un hilo por cliente: cada
FanimplementaRunnabley se ejecuta en su propioThread, simulando accesos concurrentes a un recurso limitado (el aforo). Semaphoreen modo fair: las taquillas se modelan connew Semaphore(taquillas, true). Los permisos limitan cuántos fans compran a la vez y el modo justo (FIFO) garantiza que se atiende por orden de llegada. El permiso se libera siempre en un bloquefinallypara no bloquear la cola aunque falle la compra.- Actualización segura de la UI desde hilos: los hilos de los fans nunca tocan la interfaz directamente; todos los mensajes pasan por
Platform.runLater(), que delega la actualización en el hilo de JavaFX (JavaFX Application Thread). - Colección thread-safe: la lista de espera es un
Collections.synchronizedList, de forma que varios hilos pueden añadir fans sin condiciones de carrera. - Sincronización de la finalización: el método
hiloTerminado()del controlador essynchronized; lleva la cuenta de hilos terminados sin carreras y, cuando todos los fans han acabado, muestra el resumen final y habilita la lista de espera. - Simulación de trabajo con
Thread.sleep()y manejo deInterruptedException.
Además, en la parte de interfaz:
- JavaFX con FXML: vistas declarativas (
vista.fxml,vistaListaEspera.fxml) con sus controladores, estilos en CSS y una segunda ventana modal (Modality.APPLICATION_MODAL) para la lista de espera. - Java modular (
module-info.java) y build con Maven (pluginjavafx-maven-plugin).
Requisitos: JDK 21 (JavaFX 21 viene como dependencia de Maven, no hace falta instalarlo aparte).
cd CampoFutbolFX
./mvnw clean javafx:run # Linux / macOS
mvnw.cmd clean javafx:run # WindowsCampoFutbolFX/
├── pom.xml # Maven: JavaFX 21, Java 21, javafx-maven-plugin
└── src/main/
├── java/
│ ├── module-info.java
│ └── org/example/campofutbolfx/
│ ├── Campo.java # Modelo: aforo, precio, recaudación y semáforo de taquillas
│ ├── Fan.java # Runnable: ciclo de vida de cada aficionado (hilo)
│ ├── ControladorFX.java # Controlador principal: formulario, simulación y sincronización
│ ├── ControladorLista.java# Controlador de la ventana de lista de espera
│ └── MainApp.java # Punto de entrada alternativo de la aplicación
└── resources/org/example/campofutbolfx/
├── vista.fxml # Ventana principal (configuración + log de simulación)
├── vistaListaEspera.fxml # Ventana modal con la lista de espera
└── styles.css
Proyecto académico — DAM · PSP · devPatuel