Very nice article on this topic with various solutions and comments including benchmarks here:
How to Synchronize Blocks by the Value of the Object in Java
At the end of article you can find maven link to xsync library which implements solution described in the article.