9
votes

Définir la limite de temps d'exécution sur une méthode en Java

J'ai une méthode qui renvoie une chaîne.

est-il possible qu'après un certain temps, si le seuil est excédé pour cette méthode, de renvoyer une chaîne spécifique?


2 commentaires

Ce que vous voulez, c'est appeler votre méthode et si son temps d'exécution dépasse un certain montant, la chaîne de retour est une constante?


@reef NOP, lorsque la méthode X qui renvoie une chaîne atteint I.e. 6 secondes d'exécution du temps qu'il renvoie une chaîne d'erreur. Ou simplement avoir une sorte de rappel que je peux utiliser pour gérer l'erreur de temps.


5 Réponses :


16
votes

the bibliothèque de goyaves a une très belle TIMELIMITER que Vous permet de le faire sur n'importe quelle méthode définie par une interface. Il peut générer un proxy pour votre objet qui a un délai d'attente "intégré".


4 commentaires

Cela me semble, laissez-moi vous demander cela, cet exemple n'est pas clair pour moi parce que je suis un noob, pour renvoyer la valeur de cible.Somemethod () , ce cible < / Code> Reportez-vous à l'instance de classe?


Une autre question, que si cette méthode ouvre certaines sessions, sera-t-elle fermée? Ou je dois mettre ces sessions de close avant de retourner la valeur par défaut?


@Londres. 1) Oui c'est ce que cela signifie. 2) La méthode doit fermer ces sessions à l'aide d'un essayer {...} enfin {...} . Mais ça devrait le faire quand même !!!


L'appelant tient et retournera la chaîne, mais le réel exécutable peut toujours fonctionner et continuer à courir.



11
votes

J'ai fait quelque chose de similaire dans le passé lors de la reproduction d'un processus externe avec runtime.getruntime (). Exec (commande) . Je pense que vous pouvez faire quelque chose comme celui-ci dans votre méthode: xxx

et voici interruptmertask xxx


2 commentaires

"Scédule" n'est pas utilisé comme une limite de temps, mais comme retard ... alors "waittimeout" dans ce cas est le retard avant l'exécution d'InterruptMertasTask ... de l'API: Planifie la tâche spécifiée pour l'exécution après le délai spécifié .


Je reçois une erreur dans l'essai / Catch: bloc de capture inaccessible pour une interruptionException. Cette exception n'est jamais lancée à partir du corps de la déclaration d'essai.



1
votes

Comme répondant @marcos

J'ai trouvé le délai d'attente n'est pas soulevé si la méthode verrouille quelque chose et ne libère pas le temps de la CPU sur la minuterie. Puis la minuterie ne peut pas démarrer un nouveau thread. Donc, je change un peu en démarrant le fil immédiatement et dormez à l'intérieur du fil. P>

        InterruptTimerTaskAddDel interruptTimerTask = new InterruptTimerTaskAddDel(
                Thread.currentThread(),timeout_msec);

        timer.schedule(interruptTimerTask, 0);

        /*
 * A TimerTask that interrupts the specified thread when run.
 */
class InterruptTimerTaskAddDel extends TimerTask {

    private Thread theTread;
    private long timeout;

    public InterruptTimerTaskAddDel(Thread theTread,long i_timeout) {
        this.theTread = theTread;
        timeout=i_timeout;
    }

    @Override
    public void run() {
        try {
            Thread.currentThread().sleep(timeout);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace(System.err);
        }
        theTread.interrupt();
    }

}


0 commentaires

1
votes

Vous pouvez utiliser AOP et un @ @ Télégé code> annotation de JCABI-Aspects (je suis un Développeur):

@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
  while (true) {
    if (Thread.currentThread.isInterrupted()) {
      throw new IllegalStateException("time out");
    }
    // execution as usual
  }
}


0 commentaires

0
votes

Voici un exemple à l'aide de GUAVA SIMPLETIMELIMItre CODE>

import com.google.common.util.concurrent.SimpleTimeLimiter;
import com.google.common.util.concurrent.TimeLimiter;

import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;

class TimeoutExample {

    public static void main(String[] args) throws InterruptedException, TimeoutException, ExecutionException {
        TimeLimiter timeLimiter = SimpleTimeLimiter.create(Executors.newSingleThreadExecutor());
        Duration timeout = Duration.ofMillis(500);

        String result = timeLimiter.callWithTimeout(() -> possiblyLongMethod(100), timeout); // will return
        System.out.println(result);
        String result2 = timeLimiter.callWithTimeout(() -> possiblyLongMethod(1000), timeout); // will timeout
        System.out.println(result2);

    }

    public static String possiblyLongMethod(int runtime) throws InterruptedException {
        Thread.sleep(runtime);
        return "Ran for " + runtime + "ms";
    }
}


0 commentaires