<div dir="ltr">This isn't always an option. For example, ExecutorService#awaitTermination has no such overload.</div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr">----<div><b><font color="#000099">Josh Humphries</font></b></div><div><div><span style="color:rgb(153,153,153);font-family:arial;font-size:small">Manager, Shared Systems  |  Platform Engineering</span><br></div><div><font color="#999999">Atlanta, GA  |  678-400-4867</font></div></div><div><b style="color:rgb(0,0,0)">Square</b><font color="#000000"> (</font><a href="http://www.squareup.com" target="_blank"><font color="#999999">www.squareup.com</font></a><font color="#000000">)</font></div></div></div></div>
<br><div class="gmail_quote">On Thu, Apr 28, 2016 at 10:58 AM, Alex Otenko <span dir="ltr"><<a href="mailto:oleksandr.otenko@gmail.com" target="_blank">oleksandr.otenko@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">It seems insane to pass MAX_VALUE or MAX_VALUE/2 where the caller means “forever”. Use the call without the timeout, that’s what they are for. Them behaving in (observably) the same way as the timed waits with MAX_VALUE passed in, is an implementation detail. Passing a value that has the intended meaning is the caller responsibility.<br>
<span class="HOEnZb"><font color="#888888"><br>
Alex<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> On 20 Apr 2016, at 20:26, Justin Sampson <<a href="mailto:jsampson@guidewire.com">jsampson@guidewire.com</a>> wrote:<br>
><br>
> Peter, I had exactly the same funny feeling as you when I first saw<br>
> this idiom. A few years back, Martin changed some of my timing code<br>
> in Guava's Monitor class from something like this:<br>
><br>
>  long timeoutNanos = unit.toNanos(time);<br>
>  long startNanos = System.nanoTime();<br>
>  ...<br>
>  long remainingNanos =<br>
>      timeoutNanos - (System.nanoTime() - startNanos);<br>
><br>
> to something like this:<br>
><br>
>  long timeoutNanos = unit.toNanos(time);<br>
>  long deadline = System.nanoTime() + timeoutNanos;<br>
>  ...<br>
>  long remainingNanos = deadline - System.nanoTime();<br>
><br>
> At first I thought that this would introduce some kind of overflow<br>
> error with MAX_VALUE, but I wrote a unit test for it and it passed!<br>
> Only then did I realize that these two constructs are exactly<br>
> identical in runtime behavior due to the arithmetic wraparound of<br>
> long values. Any overflow bugs triggered by one would have been<br>
> triggered by the other just as well.<br>
><br>
> (For anyone who thinks MAX_VALUE isn't interesting because it's a<br>
> centuries-long timeout, consider someone passing MAX_VALUE into an<br>
> API with the intention of "actually, don't timeout this call." If<br>
> there were an arithmetic overflow bug that caused it to, say,<br>
> timeout immediately instead of never, that would be a very<br>
> noticeable and reproducible issue.)<br>
><br>
> Now, that's not quite the end of the story. It turns out that<br>
> there's no overflow bug for MAX_VALUE as long as nanoTime() actually<br>
> progresses forward, but there IS an overflow bug for MIN_VALUE, and<br>
> there IS an overflow bug for MAX_VALUE if nanoTime() ever goes<br>
> backward.<br>
><br>
> For the MIN_VALUE case, consider for simplicity that the first call<br>
> to nanoTime() returns 0 and the second call returns 1. Then with<br>
> either of the constructs above, remainingNanos ends up equal to<br>
> MIN_VALUE-1, which is actually MAX_VALUE. Without additional guard<br>
> clauses, that could result in blocking forever rather than not at<br>
> all, which is what MIN_VALUE should mean (as with any non-positive<br>
> timeout). The fix is simply to check for time <= 0 before doing any<br>
> of these calculations, but this bug has actually slipped into the<br>
> some parts of the JDK before -- and all my testing and agonizing<br>
> over Martin's change in Guava helped find and fix one or two such<br>
> cases in the JDK! :)<br>
><br>
> For the MAX_VALUE case, there's only an overflow bug if nanoTime()<br>
> goes backward, causing some negative value to be subtracted from<br>
> MAX_VALUE in the code above. That should never happen in HotSpot,<br>
> but there have been occasional bugs and experimental "optimizations"<br>
> in other JVMs that allow it to be seen. JDK code is NOT written to<br>
> be robust to that possibility, which would slightly complicate the<br>
> code everywhere that a timeout is checked.<br>
><br>
> There is ONE remaining overflow situation that we really can't do<br>
> anything about: When the elapsed time between two calls to<br>
> nanoTime() actually exceeds 2^63-1. I'm personally willing to ignore<br>
> that one!<br>
><br>
> Cheers,<br>
> Justin<br>
><br>
> _______________________________________________<br>
> Concurrency-interest mailing list<br>
> <a href="mailto:Concurrency-interest@cs.oswego.edu">Concurrency-interest@cs.oswego.edu</a><br>
> <a href="http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel="noreferrer" target="_blank">http://cs.oswego.edu/mailman/listinfo/concurrency-interest</a><br>
<br>
<br>
_______________________________________________<br>
Concurrency-interest mailing list<br>
<a href="mailto:Concurrency-interest@cs.oswego.edu">Concurrency-interest@cs.oswego.edu</a><br>
<a href="http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel="noreferrer" target="_blank">http://cs.oswego.edu/mailman/listinfo/concurrency-interest</a><br>
</div></div></blockquote></div><br></div>