AsyncSemaphore
An interface representing a non-blocking semaphore.
A semaphore maintains a set of permits and each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing an acquirer.