"Semaphore objects allow you to specify exactly how many threads can concurrently run a piece of code, e.g. to allow at most 2 threads to concurrently run methodX(), you could specify all calls to methodX() wrapped with Semaphore.acquire() and Semaphore.release() calls, where the Semaphore is defined with 2 permits, e.g. new Semaphore(2, true)."