Current implementation of "obtainSendWindow" and Stream "sendWindow" doesn't provide atomicity for "take" operation due to natural randomness of "wait/notifyAll" operations.
When multiple threads are trying to get a portion of sendWindow (calling "obtainSendWindow"), each thread may capture and hold amount of send window which is not enough to send its own data causing continue waiting and exhausting whole sending window. And all threads are blocked on obtainSendWindow.
At the same moment overall sending window is large enough to send data and server doesn't send WINDOW_UPDATE frame.
For example:
- 32 threads
- max data frame size is 16K.
- connection send window is 64K-1.
- each thread is trying to send more than 1 full size data frame.
At this situation each thread captures and holds ~1K-3K portion of sending window, full sending window is exhausted and each sending thread is waiting (forever) to reach 16K.
Solution: Use Semaphore, which provides required atomicity and works faster.
Fix is suggested and available here: http://cr.openjdk.java.net/~skuksenko/jep110/8162497/webrev.00/