Java Concurrency


Java Concurrency Tutorial – Semaphores

Useful Tricks with Semaphores

One interesting property of Semaphores in Java is that release doesn’t have to be called by the same thread as acquire. This means you could have a thread limiter that pools or creates threads based on a semaphore by calling acquire(). Then, the running thread could release its own semaphore permit when it completes. This is a useful property that we don’t have with normal mutexes in Java.

Another trick is to increase the number of permits at runtime. Contrary to what you might guess, the number of permits in a semaphore isn’t fixed, and a call to release() will always increment the number of permits, even if no corresponding acquire() call was made. Note that this can also result in bugs if you are incorrectly calling release() when no acquire() was made.

Finally, there are a few useful methods to be familiar with in Java’s Semaphore. The method acquireInterruptibly() will acquire a resource, reattempting if it is interrupted. This means no outside handling of InterruptedException. The method tryAcquire() allows us to limit how long we will wait for a permit – we can either return immediately if there is no permit to obtain, or wait a specified timeout. If you somehow have known deadlocks that you can’t fix easily or track down, you could help prevent locking up processes by using tryAcquire() with suitable timeouts.


What are some possible uses for counting semaphores? The following come to mind:

  • Limiting concurrent access to disk (this can kill performance due to competing disk seeks)
  • Thread creation limiting
  • JDBC connection pooling / limiting
  • Network connection throttling
  • Throttling CPU or memory intensive tasks
Home » Java » Core Java » Java Concurrency Tutorial – Reentrant Locks

About Craig Flichel

Java Concurrency Tutorial – Reentrant Locks

Java’s synchronized keyword is a wonderful tool – it allows us a simple and reliable way to synchronize access to critical sections and it’s not too hard to understand.But sometimes we need more control over synchronization. Either we need to control types of access (read and write) separately, or it is cumbersome to use because either there is no obvious mutex or we need to maintain multiple mutexes.

Thankfully, lock utility classes were added in Java 1.5 and make these problems easier to solve.

2. Java Reentrant Locks