Comment définir une minuterie, par exemple pendant 2 minutes, pour essayer de se connecter à une base de données, puis lever une exception en cas de problème de connexion?
Coul l'OP clarifier s'ils souhaitent simplement tenter l'action pendant au moins 2 minutes, ou si l'exception doit être lancée maintenant plus tard dans les deux minutes, même si une tentative de connexion est actuellement en cours
thecoshman
Réponses:
280
Donc, la première partie de la réponse est de savoir comment faire ce que le sujet demande, car c'est ainsi que je l'ai initialement interprété et quelques personnes ont semblé trouver utile. La question a été clarifiée depuis et j'ai élargi la réponse pour y répondre.
Réglage d'une minuterie
Vous devez d'abord créer un minuteur (j'utilise la java.utilversion ici):
import java.util.Timer;
..
Timer timer =newTimer();
Pour exécuter la tâche une fois que vous le feriez:
timer.schedule(newTimerTask(){@Overridepublicvoid run(){// Your database code here}},2*60*1000);// Since Java-8
timer.schedule(()->/* your database code here */,2*60*1000);
Pour que la tâche se répète après la durée que vous feriez:
timer.scheduleAtFixedRate(newTimerTask(){@Overridepublicvoid run(){// Your database code here}},2*60*1000,2*60*1000);// Since Java-8
timer.scheduleAtFixedRate(()->/* your database code here */,2*60*1000,2*60*1000);
Faire une tâche timeout
Pour faire spécifiquement ce que demande la question clarifiée, c'est-à-dire tenter d'exécuter une tâche pendant une période donnée, vous pouvez procéder comme suit:
ExecutorService service =Executors.newSingleThreadExecutor();try{Runnable r =newRunnable(){@Overridepublicvoid run(){// Database task}};Future<?> f = service.submit(r);
f.get(2,TimeUnit.MINUTES);// attempt the task for two minutes}catch(finalInterruptedException e){// The thread was interrupted during sleep, wait or join}catch(finalTimeoutException e){// Took too long!}catch(finalExecutionException e){// An exception from within the Runnable task}finally{
service.shutdown();}
Cela s'exécutera normalement avec des exceptions si la tâche se termine dans les 2 minutes. Si elle s'exécute plus longtemps que cela, TimeoutException sera levée.
Un problème est que bien que vous obteniez une TimeoutException après les deux minutes, la tâche continuera en fait à s'exécuter , bien que vraisemblablement une base de données ou une connexion réseau finira par expirer et lèvera une exception dans le thread. Mais sachez que cela pourrait consommer des ressources jusqu'à ce que cela se produise.
Oh, je suppose que vous avez mal compris mon problème, je dois essayer à plusieurs reprises de me connecter à la base de données jusqu'à 2 minutes à chaque fois
Ankita
Je suis désolé mais mon exigence est que je veuille donner 2 minutes pour me connecter à la base de données, puis cela lancera juste un message d'erreur.C'est comme si je voulais définir une limite de temps pour essayer de me connecter à la base de données
Ankita
7
ATTENTION AUX LECTEURS: Cette réponse est manifestement erronée. Il définit un minuteur pour attendre 2 minutes, puis exécuter une requête de base de données après ce délai de 2 minutes, puis il l'exécute encore et encore toutes les 2 minutes. Ce qu'il ne fait PAS, c'est d'exécuter la requête DB tout de suite, puis d'échouer après 2 minutes, ce que je pense que la question a demandé (comme précisé dans le commentaire).
AgilePro
2
@AgilePro C'était vrai. Je n'ai pas répondu à la question car elle a finalement été posée et je l'ai maintenant mise à jour pour y répondre.
andrewmu
1
@ErnestasGruodis Les API principales répertorient le constructeur comme public: docs.oracle.com/javase/7/docs/api/java/util/Timer.html#Timer () Vous pouvez avoir une classe Timer différente dans votre chemin de classe - essayez java. util.Timer comme classe.
andrewmu
25
Utilisez ceci
long startTime =System.currentTimeMillis();long elapsedTime =0L.while(elapsedTime <2*60*1000){//perform db poll/check
elapsedTime =(newDate()).getTime()- startTime;}//Throw your exception
hmm ... cela fonctionnerait techniquement, sauf que cela ne couvre pas les cas
marginaux
1
C'est la seule bonne réponse. Il fonctionnera sur un seul thread et calculera l'heure de fin sans dérive. Utiliser une TimerTask est exactement la mauvaise chose à faire dans ce cas. Je suis surpris de voir combien d'exemples sur StackOverflow suggèrent ce même genre de chose qui ne va pas.
AgilePro du
1
@thecoshman - les implémentations de temporisateur n'interrompent PAS l'opération DB une fois qu'elle est en cours, ni cela. Dans tous les cas, vous ne pouvez contrôler que l'heure à laquelle vous démarrez l'opération DB. Il y a une idée fausse courante selon laquelle vous avez besoin d'un «minuteur» pour chronométrer les choses, mais ce n'est pas le cas. Vous n'avez qu'à FAIRE quelque chose, et en utilisant l'heure actuelle, assurez-vous de ne pas le FAIRE trop longtemps.
AgilePro
disons que vous devez soit retourner la connexion ou jeter après EXACTEMENT deux minutes, cela ne fonctionnera pas. ce sera le cas si APRÈS deux minutes de tentative de connexion, vous ne parvenez toujours pas à vous connecter. Dans une situation où la vérification de la connexion prend par exemple deux semaines, cela prendra autant de temps pour lever une exception.
thecoshman
14
C'est en fait un très mauvais style de codage, car la boucle while s'exécute constamment et vérifie les trucs ... mauvais pour le processeur et mauvais pour la durée de vie de la batterie.
Infinite
11
Ok, je pense que je comprends votre problème maintenant. Vous pouvez utiliser un Future pour essayer de faire quelque chose, puis expirer au bout d'un moment si rien ne s'est passé.
Par exemple:
FutureTask<Void> task =newFutureTask<Void>(newCallable<Void>(){@OverridepublicVoid call()throwsException{// Do DB stuffreturnnull;}});Executor executor =Executors.newSingleThreadScheduledExecutor();
executor.execute(task);try{
task.get(5,TimeUnit.SECONDS);}catch(Exception ex){// Handle your exception}
Une exception est levée mais le programme ne se termine pas. Veuillez m'aider à résoudre ce problème.
Ankita
2
Vous pouvez utiliser la classe ExecutorService au lieu de Executor. Il a la méthode shutdown () pour arrêter l'exécuteur.
Rites
1
Les exécuteurs avalent les exceptions lancées que vous ne gérez pas spécifiquement dans votre Callable / Runnable. Si votre Runnable / Callable n'attrape pas et ne gère pas l'exception elle-même et qu'elle vous est fournie par rapport à vous en êtes propriétaire, vous devez sous-classer ScheduledExecutorService et remplacer afterExecute (assurez-vous d'appeler super.afterExecute ()). Le deuxième argument de afterExecute sera le jetable de Runnable / Callable
adam
3
new java.util.Timer().schedule(newTimerTask(){@Overridepublicvoid run(){System.out.println("Executed...");//your code here //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly }},1000*5,1000*5);
copiez simplement le pest au-dessus du code, cela fonctionnera bien. J'ai donné deux fois le «temps», le premier est pour la première fois pour exécuter ce code et le second est pour le temps d'intervalle.
Réponses:
Donc, la première partie de la réponse est de savoir comment faire ce que le sujet demande, car c'est ainsi que je l'ai initialement interprété et quelques personnes ont semblé trouver utile. La question a été clarifiée depuis et j'ai élargi la réponse pour y répondre.
Réglage d'une minuterie
Vous devez d'abord créer un minuteur (j'utilise la
java.util
version ici):..
Pour exécuter la tâche une fois que vous le feriez:
Pour que la tâche se répète après la durée que vous feriez:
Faire une tâche timeout
Pour faire spécifiquement ce que demande la question clarifiée, c'est-à-dire tenter d'exécuter une tâche pendant une période donnée, vous pouvez procéder comme suit:
Cela s'exécutera normalement avec des exceptions si la tâche se termine dans les 2 minutes. Si elle s'exécute plus longtemps que cela, TimeoutException sera levée.
Un problème est que bien que vous obteniez une TimeoutException après les deux minutes, la tâche continuera en fait à s'exécuter , bien que vraisemblablement une base de données ou une connexion réseau finira par expirer et lèvera une exception dans le thread. Mais sachez que cela pourrait consommer des ressources jusqu'à ce que cela se produise.
la source
Utilisez ceci
la source
Ok, je pense que je comprends votre problème maintenant. Vous pouvez utiliser un Future pour essayer de faire quelque chose, puis expirer au bout d'un moment si rien ne s'est passé.
Par exemple:
la source
la source
[Android] si quelqu'un cherche à implémenter un minuteur sur Android en utilisant java .
la source