Java の Semaphore は acquire しなくても release できる
タイトルの通り。Javadoc にも書いてある。
https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/Semaphore.html#release()
There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire(). Correct usage of a semaphore is established by programming convention in the application.
acquire
していたかどうかに関係なく、release
すれば新たに acquire
可能な permit が増える。どこまでいけるかというと、内部的に int
で状態を管理しているので、Integer.MAX_VALUE
まで。それ以上に release
しようとすると、java.lang.Error
が発生する。
そもそも普通はこの仕様を意図的に利用することは無いと思う (しやめてほしい) けど、プログラムのバグでうっかり acquire
に対して release
しすぎてしまうことはある。そのときに、過剰に release
した permit が Integer.MAX_VALUE
に到達するまでは動いてしまうので困りもの。アプリ側でちゃんとやってねと言われても……と思いつつ、まあそういうことなので、そのあたりは自分たちでラップして仕組み化したほうがいいかもしれない。