Sobes.tech
Middle

¿Qué son los bloqueos optimistas y pesimistas?

sobes.tech AI

Respuesta de la IA

Los bloqueos optimistas y pesimistas son enfoques para gestionar el acceso paralelo a datos compartidos en entornos concurrentes (aplicaciones multihilo, bases de datos).

Bloqueo pesimista:

Supone que los conflictos al acceder a los datos son probables. Antes de acceder a un recurso, el hilo o transacción lo bloquea (de forma exclusiva o compartida). Otros hilos que intenten acceder a él esperarán hasta que se libere el bloqueo.

  • Ventajas: Garantiza la integridad de los datos, es simple de implementar en entornos con baja competencia.
  • Desventajas: Puede causar bloqueos (esperas), reducir la capacidad de procesamiento en alta competencia (deadlocks).
  • Ejemplos: la palabra clave synchronized en Java, bloqueos a nivel de filas o tablas en bases de datos.
// Ejemplo de bloqueo pesimista en Java
public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // Bloqueo en el objeto, solo un hilo puede ejecutar este método a la vez
    }

    public synchronized int getCount() {
        return count;
    }
}

Bloqueo optimista:

Supone que los conflictos al acceder a los datos son poco probables. El acceso a los datos se realiza sin bloqueos. Antes de guardar cambios, se verifica que los datos no hayan sido modificados por otro hilo desde que se leyeron. Si hubo cambios, la operación se cancela y generalmente se intenta de nuevo (retry).

  • Ventajas: Alta capacidad de procesamiento en entornos con baja competencia, sin problemas de deadlocks.
  • Desventajas: Pueden surgir conflictos que requieren reintentos, lo que complica la lógica. No es adecuado para operaciones de larga duración o con alta probabilidad de conflictos.
  • Ejemplos: operaciones Compare-And-Swap (CAS), gestión de versiones en bases de datos (por ejemplo, uso de columnas de versión o marcas de tiempo).
// Ejemplo de bloqueo optimista usando CAS (java.util.concurrent.atomic)
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        // Intento de incrementar de forma atómica
        // Si el valor cambió entre la lectura y la actualización, se reintenta
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

Comparación:

Característica Bloqueo pesimista Bloqueo optimista
Suposición Los conflictos son probables Los conflictos son poco probables
Enfoque Bloqueo hasta el acceso Acceso sin bloqueo, verificación al guardar
En entornos de alta competencia Puede causar bloqueos, reducir la capacidad Reintentos frecuentes, reducir el rendimiento
En entornos de baja competencia Puede generar sobrecarga Alta capacidad de procesamiento
Problema de deadlock Posible Imposible (desde la perspectiva del acceso concurrente a recursos)