es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Inicie la ejecución si aún no está en progreso, de lo contrario, espere a que la ejecución existente termine en la llamada concurrente del método Java.

Imagina que tengo una clase cuyo método (proceso) puede ser llamado concurrentemente.
Este método realiza un procesamiento (hacerProceso) que no puede ser ejecutado concurrentemente. Además, si se llama al método proceso, pero el procesamiento (hacerProceso) ya está en progreso, la invocación del método proceso debe esperar hasta que el procesamiento (hacerProceso) ya iniciado se termine y luego regresar (sin comenzar un nuevo procesamiento – hacerProceso). Llamar al método proceso solo realizará el procesamiento real (hacerProceso) si ninguno de los hilos está realizando el procesamiento real (hacerProceso) todavía.

¿Cuál sería el primitivo de concurrencia (java.util.concurrent) previsto para el problema de concurrencia descrito en el ejemplo imaginario anterior? Pensé en ReentrantLock pero no ofrece awaitUnlocked. Y la clase Condition de java.util.concurrent.locks parece demasiado básica para este caso de uso simple.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El primitivo de concurrencia deseado para el escenario descrito sería un java.util.concurrent.CountDownLatch. Se puede utilizar para bloquear un hilo hasta que ocurra un número determinado de eventos. En este caso, podemos usarlo para bloquear el método process hasta que el método doProcess haya terminado de ejecutarse.

    Aquí tienes un ejemplo de cómo se podría implementar esto:

    import java.util.concurrent.CountDownLatch
    import java.util.concurrent.locks.ReentrantLock
    
    class MyResource() {
        private val lock = ReentrantLock()
        private val processingLatch = CountDownLatch(1)
    
        fun process() {
            // Intenta adquirir el bloqueo, pero espera hasta que esté disponible
            lock.lock()
    
            // Si otro hilo ya está procesando, espera a que termine
            if (processingLatch.count > 0) {
                processingLatch.await()
                lock.unlock()
                return
            }
    
            try {
                doProcess()
            } finally {
                processingLatch.countDown()
                lock.unlock()
            }
        }
    
        private fun doProcess() {
            // Aquí va el código real de procesamiento
        }
    }
    

    En esta implementación, processingLatch se utiliza para bloquear el método process hasta que el método doProcess haya terminado de ejecutarse. Cuando un hilo adquiere el lock, verifica si el processingLatch ya se ha contado hasta cero. Si no es así, espera a que el latch se cuente antes de liberar el lock y retornar. Cuando doProcess haya terminado de ejecutarse, se cuenta hacia abajo el processingLatch, permitiendo que los hilos en espera puedan continuar.

Comments are closed.