### Question:
LatchMap { Latch takeOrAwaitLatch( long identifier ) { int index = index( identifier ); Latch latch = getLatch( index ); while ( latch == null ) { latch = new Latch(); if ( compareAndSetLatch( index, null, latch ) ) { latch.latchMap = this; latch.index = index; return latch; } latch = getLatch( index ); } latch.await(); return null; } LatchMap();   }### Answer:
@Test void takeOrAwaitLatchMustReturnLatchIfAvailable() { BinaryLatch latch = latches.takeOrAwaitLatch( 0 ); assertThat( latch, is( notNullValue() ) ); latch.release(); }
@Test void takeOrAwaitLatchMustAwaitExistingLatchAndReturnNull() throws Exception { AtomicReference<Thread> threadRef = new AtomicReference<>(); BinaryLatch latch = latches.takeOrAwaitLatch( 42 ); assertThat( latch, is( notNullValue() ) ); ExecutorService executor = Executors.newSingleThreadExecutor(); Future<BinaryLatch> future = executor.submit( () -> { threadRef.set( Thread.currentThread() ); return latches.takeOrAwaitLatch( 42 ); } ); Thread th; do { th = threadRef.get(); } while ( th == null ); ThreadTestUtils.awaitThreadState( th, 10_000, Thread.State.WAITING ); latch.release(); assertThat( future.get( 1, TimeUnit.SECONDS ), is( nullValue() ) ); }
@Test void takeOrAwaitLatchMustNotLetUnrelatedLatchesConflictTooMuch() throws Exception { BinaryLatch latch = latches.takeOrAwaitLatch( 42 ); assertThat( latch, is( notNullValue() ) ); ExecutorService executor = Executors.newSingleThreadExecutor(); Future<BinaryLatch> future = executor.submit( () -> latches.takeOrAwaitLatch( 33 ) ); assertThat( future.get( 1, TimeUnit.SECONDS ), is( notNullValue() ) ); latch.release(); }
@Test void latchMustBeAvailableAfterRelease() { latches.takeOrAwaitLatch( 42 ).release(); latches.takeOrAwaitLatch( 42 ).release(); }