### Question:
DistributedSemaphore extends Semaphore implements SyncPrimitive { @Override public abstract boolean tryAcquire(); DistributedSemaphore(); @Override abstract void acquire(); @Override abstract void acquireUninterruptibly(); @Override abstract boolean tryAcquire(); @Override boolean tryAcquire(long timeout, TimeUnit unit); abstract boolean tryAcquire(Duration timeout); @Override abstract void release(); @Override abstract void acquire(int permits); @Override abstract void acquireUninterruptibly(int permits); @Override abstract boolean tryAcquire(int permits); @Override boolean tryAcquire(int permits, long timeout, TimeUnit unit); abstract boolean tryAcquire(int permits, Duration timeout); @Override abstract void release(int permits); @Override abstract int availablePermits(); @Override abstract int drainPermits(); @Override abstract boolean isFair(); @Override abstract AsyncDistributedSemaphore async();  }### Answer:
@Test(timeout = 60000) public void testExpireRace() throws Exception { int testCount = 10000; int threads = Runtime.getRuntime().availableProcessors(); ExecutorService executorService = Executors.newFixedThreadPool(threads); Atomix atomix = atomix(); List<Future<?>> taskFuture = new ArrayList<>(threads); AtomicInteger acquired = new AtomicInteger(); for (int i = 0; i < threads; i++) { taskFuture.add(executorService.submit(() -> { DistributedSemaphore semaphore = atomix.semaphoreBuilder("test-semaphore-race") .withProtocol(protocol()) .withInitialCapacity(testCount) .build(); while (acquired.get() < testCount) { try { if (semaphore.tryAcquire(Duration.ofMillis(1))) { acquired.incrementAndGet(); } } catch (InterruptedException e) { fail(); } } })); } for (Future<?> future : taskFuture) { future.get(); } executorService.shutdown(); }