7
votes

Comment faire une fonction de fonction non bloquante retardée

Je veux appeler la fonction ajouter d'un hashset avec un délai, mais sans bloquer le fil actuel. Existe-t-il une solution facile pour réaliser quelque chose comme ceci: xxx


4 commentaires

Les réponses directes à votre question sont ci-dessous. Mais que tentent de faire semble plutôt non naturel, ce qui suggère que vous devriez peut-être rechercher une solution entièrement différente. Voulez-vous fournir un certain contexte pourquoi vous voulez retarder l'ajout?


J'utilise Storm pour mettre en œuvre un robot. Les URL à ramper sont générées par un motif contenant un identifiant de thread et un identifiant de carte. La nature du chroupleur ne permet qu'une seule URL par conseil d'être traitée à tout moment. Mon hashset contient tous les identifiants de planches actuellement libres de ramper. Le rampant d'une seule URL peut échouer pour différentes raisons (le fil a été supprimé, 404, ...). Certaines raisons permettent de réessayer les rampants. Les informations sur ces raisons sont enregistrées dans une DB qui ne verrouille pas, il devrait donc y avoir un retard avant de décider soit de réessayer.


Cela semble inutilement compliqué. Pourquoi les fils rampants ne peuvent-ils pas traiter la valeur de retour et réessayer directement lorsqu'il y avait une panne récupérable, ou au moins ajouter l'URL dans la carte (une file d'attente pourrait être meilleure pour cela).


La nature de la tempête rend cela un peu plus compliquée, avec le gain de la mise à l'échelle facile et de la tolérance à la faute.


3 Réponses :


0
votes

vérifier threadpoolexecutive.schedule () méthode.


0 commentaires

10
votes

Vous pouvez utiliser PlanifiéTheadpoolExecutor.schedule : xxx

Il exécutera votre code après 1 seconde sur un thread séparé . Faites attention aux modifications simultanées de myhashset cependant. Si vous modifiez la collection en même temps à partir d'un fil différent ou si vous essayez de les utiliser, vous risquez d'avoir des problèmes et devrez utiliser des serrures.


1 commentaires

Ne pas itération sur l'ensemble lors de l'opération Ajouter n'est pas suffisant, car la visibilité de la mémoire de la modification n'est pas garantie.



12
votes

La solution de vanille ordinaire serait la suivante:

    new Thread( new Runnable() {
        public void run()  {
            try  { Thread.sleep( 1000 ); }
            catch (InterruptedException ie)  {}
            myHashSet.add( foo );
        }
    } ).start();


1 commentaires

Thread.sleep () est un appel de blocage. La création d'un nouveau fil ne bloquera pas le fil principal, mais toujours en traitement parallèle, il va toujours bloquer un fil.