Enunciado
Diseña un programa en Java que simule el funcionamiento de un estacionamiento multinivel. El estacionamiento tiene un número limitado de plazas distribuidas en varios niveles. Los vehículos llegan al parking y deben buscar una plaza libre. Si no hay plazas disponibles, el vehículo debe esperar a que alguna se libere.
Requisitos
- Clases necesarias:
- Una clase
Parking
que gestione las plazas libres en los diferentes niveles. - Una clase
Vehiculo
que represente a los hilos que intentan estacionarse. - Una clase
Salida
que represente a los hilos que liberan plazas de forma aleatoria.
- Una clase
- Gestión del estacionamiento:
- El parking tiene un total de 3 niveles, cada uno con 5 plazas.
- Los vehículos deben buscar y ocupar la primera plaza libre disponible.
- Si no hay plazas libres, deben esperar.
- Los vehículos liberan las plazas después de un tiempo aleatorio.
- Sincronización:
- Usa
wait()
ynotifyAll()
para gestionar el acceso a las plazas de forma segura.
- Usa
- Simulación:
- Genera 10 vehículos que intenten estacionarse.
- Genera un hilo que libere plazas de manera aleatoria.
Implementación
import java.util.ArrayList;
import java.util.List;
class Parking {
private final int niveles;
private final int plazasPorNivel;
private final List<List<Boolean>> parking;
public Parking(int niveles, int plazasPorNivel) {
this.niveles = niveles;
this.plazasPorNivel = plazasPorNivel;
parking = new ArrayList<>();
for (int i = 0; i < niveles; i++) {
List<Boolean> nivel = new ArrayList<>();
for (int j = 0; j < plazasPorNivel; j++) {
nivel.add(false); // False indica que la plaza está libre
}
parking.add(nivel);
}
}
public synchronized int[] ocuparPlaza() throws InterruptedException {
while (true) {
for (int nivel = 0; nivel < niveles; nivel++) {
for (int plaza = 0; plaza < plazasPorNivel; plaza++) {
if (!parking.get(nivel).get(plaza)) {
parking.get(nivel).set(plaza, true);
System.out.println(Thread.currentThread().getName() + " ocupó la plaza " + plaza + " en el nivel " + nivel);
return new int[]{nivel, plaza};
}
}
}
System.out.println(Thread.currentThread().getName() + " espera por una plaza libre.");
wait(); // Espera si no hay plazas libres
}
}
public synchronized void liberarPlaza(int nivel, int plaza) {
parking.get(nivel).set(plaza, false);
System.out.println("Plaza " + plaza + " en el nivel " + nivel + " ha sido liberada.");
notifyAll(); // Notifica a los vehículos en espera
}
}
class Vehiculo implements Runnable {
private final Parking parking;
public Vehiculo(Parking parking) {
this.parking = parking;
}
@Override
public void run() {
try {
int[] plaza = parking.ocuparPlaza();
Thread.sleep((int) (Math.random() * 5000 + 1000)); // Simula el tiempo de estacionamiento
parking.liberarPlaza(plaza[0], plaza[1]);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class SimulacionParking {
public static void main(String[] args) {
Parking parking = new Parking(3, 5); // 3 niveles, 5 plazas por nivel
// Crear 10 vehículos
for (int i = 1; i <= 10; i++) {
new Thread(new Vehiculo(parking), "Vehiculo-" + i).start();
}
}
}
Requisitos de Salida
El programa debe mostrar mensajes como los siguientes (puede variar debido a la concurrencia):
Vehiculo-1 ocupó la plaza 0 en el nivel 0
Vehiculo-2 ocupó la plaza 1 en el nivel 0
Vehiculo-3 ocupó la plaza 2 en el nivel 0
Vehiculo-4 espera por una plaza libre.
Plaza 0 en el nivel 0 ha sido liberada.
Vehiculo-4 ocupó la plaza 0 en el nivel 0
...
Conceptos Evaluados
- Sincronización: Uso correcto de
synchronized
,wait()
ynotifyAll()
para coordinar el acceso a las plazas. - Gestión de recursos compartidos: Garantizar que las plazas sean ocupadas y liberadas de manera segura y sin conflictos.
- Concurrencia: Manejo de múltiples hilos que representan vehículos accediendo al estacionamiento.
Resumen
Este ejercicio combina la sincronización, la concurrencia y la gestión de recursos compartidos en un escenario práctico. Al resolverlo, se desarrollan habilidades clave en la programación multihilo para manejar sistemas concurrentes de forma segura y eficiente.