G3-Critical-Sections-Without-Bottlenecks-Lab-Java GitHub Details, Stars and Alternatives | OpenRepoFinder
jerry-felipe / repository
G3-Critical-Sections-Without-Bottlenecks-Lab-Java
Laboratorio práctico en Java 25 LTS para proteger secciones críticas sin convertir la aplicación en un cuello de botella, aplicando sincronización mínima, ReentrantLock, operaciones atómicas y medición de concurrencia.
A transparent discovery signal based on current public GitHub metadata.
Recent activity35% weight
100
Community adoption25% weight
0
Maintenance state20% weight
100
License clarity10% weight
0
Project information10% weight
68
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
README preview
Java Critical Sections Without Bottlenecks
Laboratorio práctico para aprender a proteger recursos compartidos sin convertir toda la aplicación en una fila de espera.
El proyecto compara diferentes estrategias de sincronización en Java 25 LTS, mostrando cómo el alcance de un bloqueo afecta el rendimiento, la concurrencia y la escalabilidad de una aplicación.
Idea clave: un buen lock protege únicamente el dato compartido; un mal lock secuestra toda la aplicación.
El problema
Cuando varios hilos consultan o modifican simultáneamente un mismo recurso, pueden producirse:
Condiciones de carrera.
Datos inconsistentes.
Actualizaciones perdidas.
Lecturas incorrectas.
Comportamientos impredecibles.
La solución habitual consiste en utilizar sincronización o exclusión mutua. Sin embargo, proteger demasiado código también puede provocar:
Esperas innecesarias.
Alta contención.
Mayor latencia.
Menor throughput.
Baja escalabilidad.
Hilos bloqueados por operaciones que no necesitan protección.
El verdadero reto no es simplemente agregar un lock, sino colocarlo exactamente donde se necesita.
Objetivo
Demostrar mediante código y mediciones cómo:
Identificar el estado que realmente es compartido.
Delimitar correctamente una sección crítica.
Reducir el tiempo durante el cual se mantiene un bloqueo.
Ejecutar validaciones y operaciones independientes en paralelo.
Comparar distintas estrategias de sincronización.
Medir contención, latencia y rendimiento.
Caso de estudio
El proyecto simula un sistema de reservas de inventario.
Varios hilos intentan reservar unidades de un producto al mismo tiempo. El sistema debe garantizar que:
El inventario nunca sea negativo.
No se vendan más unidades de las disponibles.
Cada actualización sea consistente.
Las operaciones independientes no sean bloqueadas.
El sistema mantenga un buen nivel de concurrencia.
Estrategias implementadas
Estrategia
Descripción
Propósito
Bloqueo amplio
Protege todo el método
ALGORITHMICALLY RELATED
Similar Open-Source Projects
Selected from shared topics, language and repository description—not editorial ratings.
Laboratorio práctico en Java 25 LTS para demostrar cómo una Race Condition puede corromper datos compartidos cuando múltiples hilos modifican el mismo estado sin control, y cómo resolver el problema usando estructuras atómicas como AtomicInteger.
Aunque solamente la lectura y modificación de stock necesitan exclusión mutua, las siguientes operaciones también quedan bloqueadas:
Validaciones.
Consultas externas.
Registro de auditoría.
Construcción de respuestas.
Notificaciones.
Esto obliga a que los hilos ejecuten en serie operaciones que podrían realizarse en paralelo.
Implementación optimizada
package com.workorderit.criticalsection.service;
import java.util.concurrent.locks.ReentrantLock;
public final class OptimizedInventoryService {
private final ReentrantLock inventoryLock = new ReentrantLock();
private int availableStock;
public OptimizedInventoryService(int initialStock) {
if (initialStock < 0) {
throw new IllegalArgumentException(
"Initial stock cannot be negative"
);
}
this.availableStock = initialStock;
}
public ReservationResult reserve(
String productId,
int quantity
) {
validateRequest(productId, quantity);
// Trabajo independiente realizado fuera del lock.
ReservationContext context = prepareReservation(
productId,
quantity
);
ReservationResult result;
inventoryLock.lock();
try {
// Solo el acceso al estado compartido forma parte
// de la sección crítica.
if (availableStock < quantity) {
result = ReservationResult.rejected(
productId,
quantity,
availableStock
);
} else {
availableStock -= quantity;
result = ReservationResult.approved(
productId,
quantity,
availableStock
);
}
} finally {
inventoryLock.unlock();
}
// Auditoría, métricas y notificaciones fuera del lock.
completeReservation(context, result);
return result;
}
public int getAvailableStock() {
inventoryLock.lock();
try {
return availableStock;
} finally {
inventoryLock.unlock();
}
}
private void validateRequest(
String productId,
int quantity
) {
if (productId == null || productId.isBlank()) {
throw new IllegalArgumentException(
"Product ID is required"
);
}
if (quantity <= 0) {
throw new IllegalArgumentException(
"Quantity must be greater than zero"
);
}
}
private ReservationContext prepareReservation(
String productId,
int quantity
) {
return new ReservationContext(productId, quantity);
}
private void completeReservation(
ReservationContext context,
ReservationResult result
) {
// Simulación de auditoría, métricas o notificaciones.
}
}
El bloque finally garantiza la liberación aunque ocurra una excepción.
4. Evitar un lock global innecesario
Los recursos independientes deberían utilizar mecanismos de sincronización independientes.
Producto A ── Lock A
Producto B ── Lock B
Producto C ── Lock C
De esta manera, una reserva del producto A no bloquea las operaciones relacionadas con los productos B y C.
5. Medir antes de optimizar
Una solución concurrente no debe evaluarse solamente porque “parece más rápida”. Debe medirse bajo carga y comprobarse que conserva la consistencia.
Preguntas que responde el proyecto
¿Qué instrucciones forman realmente la sección crítica?
¿Cuánto código debería permanecer dentro del lock?
¿Cuándo utilizar synchronized?
¿Cuándo utilizar ReentrantLock?
¿Cuándo utilizar una operación atómica?
¿Cómo evitar bloqueos prolongados?
¿Cómo detectar contención?
¿Cómo comprobar que el inventario continúa siendo consistente?
¿Cómo aumentar la concurrencia sin sacrificar seguridad?
Resultados esperados
Al completar el proyecto, el desarrollador podrá:
Detectar condiciones de carrera.
Identificar recur
Este repositorio contiene la implementación de diversas estructuras de datos vistas en la materia de Estructura de Datos, junto con sus respectivas prácticas de laboratorio. Aquí se incluyen ejemplos y ejercicios aplicados en Java Cada implementación cuenta con documentación y ejemplos prácticos para facilitar su comprensión y aplicación.