Varias llamadas a CountDownLatch.await (int) con tiempo de espera

Utilizo un CountDownLatch para esperar un determinado acontecimiento de otro componente (funcionamiento en un hilo diferente). El siguiente enfoque se ajustaría a la semántica de mi software, pero no estoy seguro de si funciona como espero:

mCountDownLatch.await(3000, TimeUnit.MILLISECONDS) otherComponent.aStaticVolatileVariable = true; mCountDownLatch.await(3500, TimeUnit.MILLISECONDS); ... <proceed with other stuff> 

El escenario debe ser el siguiente: Espero 3 segundos, y si el latch no se cuenta hasta 0, notifico al otro componente con esa variable, y luego espero como máximo 3.5 segundos. Si hay tiempo de espera de nuevo, entonces no me importa y procederá con otras operaciones.

Nota: Sé que no se ve así, pero el escenario anterior es totalmente razonable y válido en mi software.

Leí la documentación de wait (int, TimeUnit) y CountDownLatch, pero no soy un experto en Java / Android, así que necesito confirmación. Para mí, todos los escenarios parecen válidos:

  • Si la primera espera es exitosa, entonces la otra espera regresará inmediatamente
  • Si los primeros esperan tiempos fuera, entonces el otro espera aún es válido; Por lo tanto, si el otro hilo nota la señal estática, la segunda espera podría volver con éxito
  • Ambos esperan llamadas de tiempo de espera (esto está bien de acuerdo a la semántica de mi software)

¿Estoy usando esperar (…) correctamente? ¿Se puede esperar un segundo (…) en la forma anterior, incluso si una espera anterior (…) sobre el mismo objeto se ha agotado?

Si entiendo su pregunta correctamente, esta prueba demuestra que todos sus supuestos / requisitos son verdaderos / cumplidos. (Ejecutar con JUnit y Hamcrest.) Tenga en cuenta su código en el método runCodeUnderTest() , aunque está intercalado con la grabación de tiempo y los tiempos de espera se reducen en un factor de 10.

 import org.junit.Before; import org.junit.Test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.hamcrest.Matchers.closeTo; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertThat; public class CountdownLatchTest { static volatile boolean signal; CountDownLatch latch = new CountDownLatch(1); long elapsedTime; long[] wakeupTimes = new long[2]; @Before public void setUp() throws Exception { signal = false; } @Test public void successfulCountDownDuringFirstAwait() throws Exception { countDownAfter(150); runCodeUnderTest(); assertThat((double) elapsedTime, closeTo(150, 10)); assertThat(wakeupTimeSeparation(), lessThan(10)); } @Test public void successfulCountDownDuringSecondAwait() throws Exception { countDownAfter(450); runCodeUnderTest(); assertThat((double) elapsedTime, closeTo(450, 10)); assertThat((double) wakeupTimeSeparation(), closeTo(150, 10)); } @Test public void neverCountDown() throws Exception { runCodeUnderTest(); assertThat((double) elapsedTime, closeTo(650, 10)); assertThat((double) wakeupTimeSeparation(), closeTo(350, 10)); } @Test public void countDownAfterSecondTimeout() throws Exception { countDownAfter(1000); runCodeUnderTest(); assertThat((double) elapsedTime, closeTo(650, 10)); assertThat((double) wakeupTimeSeparation(), closeTo(350, 10)); } @Test public void successfulCountDownFromSignalField() throws Exception { countDownAfterSignal(); runCodeUnderTest(); assertThat((double) elapsedTime, closeTo(300, 10)); } private int wakeupTimeSeparation() { return (int) (wakeupTimes[1] - wakeupTimes[0]); } private void runCodeUnderTest() throws InterruptedException { long start = System.currentTimeMillis(); latch.await(300, TimeUnit.MILLISECONDS); wakeupTimes[0] = System.currentTimeMillis(); signal = true; latch.await(350, TimeUnit.MILLISECONDS); wakeupTimes[1] = System.currentTimeMillis(); elapsedTime = wakeupTimes[1] - start; } private void countDownAfter(final long millis) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { sleep(millis); latch.countDown(); } }).start(); } private void countDownAfterSignal() { new Thread(new Runnable() { @Override public void run() { boolean trying = true; while (trying) { if (signal) { latch.countDown(); trying = false; } sleep(5); } } }).start(); } private void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { throw new IllegalStateException("Unexpected interrupt", e); } } } 
  • Cómo habilitar la sincronización de la cuenta personalizada en android?
  • Cómo sincronizar contactos de teléfono en gmail en android mediante programación utilizando google contactos api
  • Android Studio 1.0 'runProguard' vs 'minifyEnabled'
  • ¿Cómo usar Git en Android?
  • ¿SyncAdapter soporta tanto la carga como la descarga durante una sincronización?
  • Juegos de sincronización de Java: sincronizados && wait && notify
  • Android sync / descargar marco
  • ¿Se puede sincronizar un Android AsyncTask doInBackground para serializar la ejecución de la tarea?
  • Sincronizar datos de aplicaciones entre iOS y Android
  • ¿Cómo recuperar el tiempo de 'última sincronización' para una cuenta?
  • Bases de datos de sincronización Mysql SQLite
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.