¿Existe una buena forma estándar de llamar a un método de bloqueo con un tiempo de espera en Java? Quiero poder hacer:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
Si eso tiene sentido.
Gracias.
java
concurrency
jjujuma
fuente
fuente
Respuestas:
Podrías usar un Ejecutor:
Si
future.get
no regresa en 5 segundos, lanza unTimeoutException
. El tiempo de espera se puede configurar en segundos, minutos, milisegundos o cualquier unidad disponible como constante enTimeUnit
.Consulte JavaDoc para obtener más detalles.
fuente
BlockingMethodCallable
cuyo constructor acepte los parámetros que desea pasarblockingMethod()
y almacénelos como variables miembro (probablemente como finales). Luego, en el interior,call()
pase esos parámetros al archivoblockMethod()
.future.cancel(true)
- El método cancel (boolean) en el tipo Future <Object> no es aplicable para los argumentos ()Puede envolver la llamada en a
FutureTask
y usar la versión de tiempo de espera de get ().Ver http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
fuente
Vea también TimeLimiter de Guava, que usa un Ejecutor detrás de escena.
fuente
También hay una solución AspectJ para eso con la biblioteca jcabi-examples .
No puede ser más sucinto, pero debes depender de AspectJ e introducirlo en tu ciclo de vida de compilación, por supuesto.
Hay un artículo que lo explica con más detalle : Limitar el tiempo de ejecución del método Java
fuente
Es realmente genial que la gente intente implementar esto de tantas maneras. Pero la verdad es que NO hay forma.
La mayoría de los desarrolladores intentarían poner la llamada de bloqueo en un hilo diferente y tener un futuro o algún temporizador. PERO no hay forma en Java de detener un hilo externamente, y mucho menos en algunos casos muy específicos como los métodos Thread.sleep () y Lock.lockInterruptibly () que manejan explícitamente la interrupción del hilo.
Entonces, realmente tienes solo 3 opciones genéricas:
Coloque su llamada de bloqueo en un nuevo hilo y si el tiempo expira, simplemente continúe, dejando ese hilo colgando. En ese caso, debe asegurarse de que el hilo esté configurado para ser un hilo Daemon. De esta manera, el hilo no evitará que su aplicación finalice.
Utilice API de Java sin bloqueo. Entonces, para la red, por ejemplo, use NIO2 y use los métodos sin bloqueo. Para leer desde la consola, use Scanner.hasNext () antes de bloquear, etc.
Si su llamada de bloqueo no es una IO, sino su lógica, entonces puede verificar repetidamente
Thread.isInterrupted()
si fue interrumpida externamente y tener otra llamada de hilothread.interrupt()
en el hilo de bloqueoEste curso sobre concurrencia https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
realmente recorre esos fundamentos si realmente desea comprender cómo funciona en Java. En realidad, habla sobre esas limitaciones y escenarios específicos, y cómo abordarlos en una de las conferencias.
Personalmente, trato de programar sin usar el bloqueo de llamadas tanto como sea posible. Existen kits de herramientas como Vert.x, por ejemplo, que hacen que sea realmente fácil y eficaz realizar operaciones de IO y no IO de forma asíncrona y sin bloqueo.
Espero que ayude
fuente
Tenga en cuenta que la parada está en desuso, la mejor alternativa es establecer una bandera booleana volátil, dentro deckingMethod () verifique y salga, así:
fuente
Prueba esto. Solución más sencilla. Garantiza que si el bloqueo no se ejecuta dentro del límite de tiempo. el proceso terminará y lanzará una excepción.
ejemplo:
fuente
Te estoy dando aquí el código completo. En lugar del método al que estoy llamando, puedes usar tu método:
fuente
Suponga que
blockingMethod
solo duerme por algunos milis:Mi solución es usar
wait()
ysynchronized
así:Entonces puedes reemplazar
something.blockingMethod(input)
a
something.blockingMethod(input, 2000)
Espero eso ayude.
fuente
Necesita una implementación de disyuntor como la presente en el proyecto a prueba de fallas en GitHub.
fuente