RFR: 8305092: Improve Thread.sleep(millis, nanos) for sub-millisecond granularity

David M. Lloyd duke at openjdk.org
Wed Mar 29 17:28:29 UTC 2023


On Wed, 29 Mar 2023 11:28:53 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:

> Java API has the `Thread.sleep(millis, nanos)` method exposed to users. The documentation for that method clearly says the precision and accuracy are dependent on the underlying system behavior. However, it always rounds up `nanos` to 1ms when doing the actual sleep. This means users cannot do the micro-second precision sleeps, even when the underlying platform allows it. Sub-millisecond sleeps are useful to build interesting primitives, like the rate limiters that run with >1000 RPS.
> 
> When faced with this, some users reach for more awkward APIs like `java.util.concurrent.locks.LockSupport.parkNanos`. The use of that API for sleeps is not in line with its intent, and while it "seems to work", it might have interesting interactions with other uses of `LockSupport`. Additionally, these "sleeps" are no longer visible to monitoring tools as "normal sleeps", e.g. as `Thread.sleep` events. Therefore, it would be prudent to improve current `Thread.sleep(millis, nanos)` for sub-millisecond granularity. 
> 
> Fortunately, the underlying code is almost ready for this, at least on POSIX side. I skipped Windows paths, because its timers are still no good. Note that on both Linux and MacOS timers oversleep by about 50us. I have a few ideas how to improve the accuracy for them, which would be a topic for a separate PR.
> 
> Additional testing:
>   - [x] New regression test
>   - [x] New benchmark
>   - [x] Linux x86_64 `tier1`
>   - [x] Linux AArch64 `tier1`

Right, I was assuming that such an implementation would be conformant to the existing specification of the `sleep` method, thus it would have to loop by consuming the unpark (if any), checking for interruption, parking for the remaining time, and reinstating the unpark at the end (if any was consumed). The main risk that I could see of such an approach is that if the sleep was interrupted, then the loop would necessarily unpark itself again (as interruption also interrupts park but this is indistinguishable from an explicit unpark), which might cause a spurious unpark down the line. But it should be pretty consistent with how it is used in interruptible locks AFAIK. I was mostly curious about other factors like JVMTI and thread status though.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/13225#issuecomment-1489010885


More information about the core-libs-dev mailing list