Existe-t-il un moyen standard d'appeler une méthode de blocage avec un délai d'expiration en Java? Je veux pouvoir faire:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
si ça a du sens.
Merci.
java
concurrency
jjujuma
la source
la source
Réponses:
Vous pouvez utiliser un exécuteur:
Si le
future.get
ne revient pas dans 5 secondes, il lance unTimeoutException
. Le délai d'expiration peut être configuré en secondes, minutes, millisecondes ou toute unité disponible en tant que constante dansTimeUnit
.Voir le JavaDoc pour plus de détails.
la source
BlockingMethodCallable
dont le constructeur accepte les paramètres que vous souhaitez passerblockingMethod()
et stockez-les en tant que variables membres (probablement comme finales). Ensuite,call()
passez ces paramètres à l' intérieurblockMethod()
.future.cancel(true)
- La méthode cancel (boolean) dans le type Future <Object> n'est pas applicable pour les arguments ()Vous pouvez encapsuler l'appel dans un
FutureTask
et utiliser la version timeout de get ().Voir http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
la source
Voir aussi TimeLimiter de Guava qui utilise un exécuteur dans les coulisses.
la source
Il existe également une solution AspectJ pour cela avec la bibliothèque jcabi-aspects .
Cela ne peut pas être plus succinct, mais vous devez compter sur AspectJ et l'introduire dans votre cycle de vie de construction, bien sûr.
Il y a un article qui l'explique plus en détail: Limiter le temps d'exécution de la méthode Java
la source
C'est vraiment génial que les gens essaient de mettre en œuvre cela de tant de façons. Mais la vérité est qu'il n'y a aucun moyen.
La plupart des développeurs essaieraient de placer l'appel de blocage dans un thread différent et d'avoir un avenir ou une minuterie. MAIS il n'y a aucun moyen en Java d'arrêter un thread en externe, sans parler de quelques cas très spécifiques comme les méthodes Thread.sleep () et Lock.lockInterruptably () qui gèrent explicitement l'interruption de thread.
Donc, vraiment, vous n'avez que 3 options génériques:
Mettez votre appel de blocage sur un nouveau thread et si le temps expire, vous passez simplement à autre chose, laissant ce fil suspendu. Dans ce cas, vous devez vous assurer que le thread est défini pour être un thread Daemon. De cette façon, le thread n'empêchera pas votre application de se terminer.
Utilisez des API Java non bloquantes. Donc pour le réseau par exemple, utilisez NIO2 et utilisez les méthodes non bloquantes. Pour lire depuis la console, utilisez Scanner.hasNext () avant de bloquer, etc.
Si votre appel de blocage n'est pas un IO, mais votre logique, vous pouvez vérifier à plusieurs reprises
Thread.isInterrupted()
s'il a été interrompu en externe et avoir un autre appel de threadthread.interrupt()
sur le thread de blocage.Ce cours sur la concurrence https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
décrit vraiment ces principes fondamentaux si vous voulez vraiment comprendre comment cela fonctionne en Java. Il parle en fait de ces limites et scénarios spécifiques, et de la façon de les aborder dans l'une des conférences.
J'essaye personnellement de programmer sans utiliser autant que possible le blocage des appels. Il existe des boîtes à outils comme Vert.x par exemple qui permettent d'effectuer très facilement et efficacement des opérations d'E / S et aucune opération d'E / S de manière asynchrone et de manière non bloquante.
J'espère que ça aide
la source
Notez que stop est obsolète, la meilleure alternative est de définir un indicateur booléen volatil, à l'intérieur de blockingMethod (), vérifiez-le et quittez, comme ceci:
la source
Essaye ça. Solution plus simple. Garantit que si le blocage ne s'est pas exécuté dans le délai imparti. le processus se terminera et lèvera une exception.
exemple :
la source
Je vous donne ici le code complet. À la place de la méthode que j'appelle, vous pouvez utiliser votre méthode:
la source
Supposons
blockingMethod
juste dormir pendant quelques millis:Ma solution est d'utiliser
wait()
etsynchronized
comme ceci:Alors tu peux remplacer
something.blockingMethod(input)
à
something.blockingMethod(input, 2000)
J'espère que ça aide.
la source
Vous avez besoin d'un disjoncteur implémentation de comme celle présente dans le projet de sécurité intégrée sur GitHub.
la source