availablePermits java semáforo con ThreadPool

Rajkumar Natarajan:

Estoy aprendiendo semáforo en Java usando el tutorial https://www.baeldung.com/java-semaphore .

La primera prueba en el tutorial (que está por debajo de uno) está trabajando muy bien.

@Test
public void givenLoginQueue_whenReachLimit_thenBlocked() {
    int slots = 10;
    ExecutorService executorService = Executors.newFixedThreadPool(slots);
    LoginQueueUsingSemaphore loginQueue = new LoginQueueUsingSemaphore(slots);
    IntStream.range(0, slots)
      .forEach(user -> executorService.execute(loginQueue::tryLogin));
    executorService.shutdown();
 
    assertEquals(0, loginQueue.availableSlots());
    assertFalse(loginQueue.tryLogin());
}

Si comento la línea executorService.shutdown();en el caso de prueba fragmento anterior entonces la prueba falla con el error más adelante.

java.lang.AssertionError: 
Expected :0
Actual   :1
<Click to see difference>
at org.testng.AssertJUnit.fail(AssertJUnit.java:59)
at org.testng.AssertJUnit.failNotEquals(AssertJUnit.java:364)
at org.testng.AssertJUnit.assertEquals(AssertJUnit.java:80)
at org.testng.AssertJUnit.assertEquals(AssertJUnit.java:245)
at org.testng.AssertJUnit.assertEquals(AssertJUnit.java:252)
at LoginQueueSemaphoreTest.givenLoginQueue_whenReachLimit_thenBlocked(LoginQueueSemaphoreTest.java:24)

Una vez que se quita el comentario y habilito la executorService.shutdown();del bien funciona la prueba.

No podía entender cómo la prueba (permisos disponibles semáforo) depende de la piscina rosca exterior. Además, ¿cómo es de 1 ranura disponible cuando no dio a conocer los permisos? Cualquier breve explicación sería útil. Gracias por adelantado.

Janus Warm Arca:

¿Este comportamiento es consistente, o qué a veces se obtiene un valor diferente para Actual(cuando la omisión de la executorService.shutdown()llamada)? Si de vez en cuando ves otros valores (digamos 2 o 3), esto sugiere fuertemente que todo esto es debido a la programación / calendario.

Trate de reemplazar executorService.shutdown()con Thread.sleep(15_000). No pasa la prueba si se hace este cambio? Si es así, entonces esto indica que lo que sucede es que el tiempo extra que se necesita para también ejecutar la shutdown()llamada es justo lo suficiente para asegurarse de que los 10 hilos pueden ser generado y llevar a cabo su trabajo (llamando tryLogin()a disminuir el Semaphore) antes de la assertEquals()que se ejecuta la llamada. Tenga en cuenta que, según la documentación , shutdown()inicie un cierre ordenado de la ExecutorServiceya que permite la ejecución de las tareas se ejecuten por completo, pero la llamada en sí no no bloquee durante ese período. Como resultado, parece que es puramente casual que el tiempo que tarda en ejecutarshutdown()es justo lo suficiente para permitir que los otros hilos para terminar. Como tal, esto no es una prueba muy buena ya que el comportamiento puede variar entre diferentes máquinas. En cambio, la prueba debería haber llamado shutdown() seguido de awaitTermination() (o, alternativamente, se usa un CountDownLatchdecremento por los trabajadores para bloquear el hilo principal) para asegurar que la assertEquals()llamada no se ejecuta hasta que después de todos los subprocesos de trabajo han terminado.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=209111&siteId=1
Recomendado
Clasificación