Comportamento de future.get com 0 tempo limite
-
27-10-2019 - |
Pergunta
Alguém pode me indicar alguma documentação que deixe claro que um 'Future.get` com um tempo limite de 0 não vai esperar?
A documentação da API para java.util.concurrent.Future
não torna explícito o comportamento de future.get(0, unit)
.Por si só, a declaração "Espera se necessário por no máximo o tempo determinado ..." implica que esta invocação não esperará, mas dado o comportamento de longa data de Object.wait(0)
(espera infinita), estou nervoso em dependerem um comportamento "sem espera" de future.get(0, unit)
Digitalizando a fonte de algumas classes fornecidas pelo JDK (viz. FutureTask
), vejo que esta implementação específica de Future
não espera quando o tempo limite é 0.
Eu gostaria de poder dizer
long timeout = Math.max(until - now, 0);
return future.get(timeout, TimeUnit.MILLISECONDS);
mas estou nervoso com a possibilidade de um futuro implementar isso como uma espera infinita, então, em vez disso, codifiquei explicitamente da maneira que esperava que funcionasse:
long timeout = Math.max(until - now, 0);
if(timeout > 0 || future.isDone()){
return future.get(timeout, TimeUnit.MILLISECONDS);
} else {
throw TimeoutException();
}
Solução
Aguarda, se necessário, no máximo o tempo determinado…
Esperar por no máximo unidades de tempo zero não é uma espera.Isso não é uma dica implícita, é uma garantia explícita.
Outras dicas
Alguém pode me indicar alguma documentação que deixe claro que um 'Future.get` com um tempo limite de 0 não vai esperar?
Posso apontar alguns códigos, se isso ajudar.Olhando para java.util.concurrent.FutureTask
e, em seguida, para AbstractQueuedSynchronizer
, vejo o seguinte loop, que reduzi para mostrar os bits relavent:
private boolean doAcquireSharedNanos(int arg, long nanosTimeout) {
long lastTime = System.nanoTime();
for (;;) {
...
if (nanosTimeout <= 0) {
cancelAcquire(node);
return false;
}
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
}
Isso significa que se nanosTimeout
for 0 (o que será se você passar 0 para obter), ele tentará adquirir o futuro uma vez e, em seguida, expirará o tempo e retornará falso.
Se você se sentir melhor, defina o tempo limite como 1 nanossegundo.