Est-il mauvais d’utiliser le polling en Java?

J’ai plusieurs ArrayLists qui fonctionnent comme des files d’attente de données. Chacune des files d’attente est liée à un thread individuel qui vérifie si cette ArrayList contient des données.

  while (array.size == 0) { // nothing } // do stuff with one element of the array // remove element from array // and call the loop again 

J’ai fait des choses similaires en programmation système intégrée, mais est-il sécuritaire de l’utiliser en Java? L’inquiétude concerne le gaspillage énergétique des processus en itérant très rapidement autour de cette boucle.

Vous pouvez résoudre ce problème en ajoutant Thread.sleep(100) et en vérifiant toutes les Thread.sleep(100) , mais encore une fois – un temps de réponse plus lent.

La question est la suivante: dois-je append ce sumil ou je ne devrais pas m’en inquiéter?

Des suggestions sur un système plus sûr / meilleur pour vérifier les nouvelles données dans les tableaux?

ArrayList n’est pas une collection thread-safe, donc si un thread ajoute des données à votre liste et qu’un autre thread tente d’extraire des données de la même liste, vous n’avez aucune garantie que l’autre thread verra les éléments ajoutés.

Et occupée à attendre comme ce que vous décrivez consum inutilement des ressources processeur.

Comme vous semblez avoir besoin d’une file d’attente, pourquoi ne pas en utiliser une, comme ArrayBlockingQueue . Il a une méthode de take qui bloque, sans consumr de cycle de traitement, l’ajout d’un élément à la file d’attente. Et c’est thread-safe.

À moins que le temps que vous devez attendre soit très court, rendant ainsi un changement de contexte trop coûteux, je n’utiliserais pas le spinning. Cela gaspille définitivement les cycles du processeur sans raison valable.

Vous devez utiliser wait/notify ou un autre mécanisme de signalisation pour suspendre le thread et le réactiver uniquement lorsque cela est nécessaire.

En ce qui concerne les constructions plus avancées, il existe des structures de données spécialisées pour les modèles producteur-consommateur, comme BlockingQueue (choisissez une implémentation):

Une queue qui prend également en charge les opérations qui attendent que la queue ne soit plus vide lors de la récupération d’un élément, et attend que l’espace soit disponible dans la queue lors du stockage d’un élément.

Pourquoi ne pas utiliser une file d’attente telle que la queue bloquante publiée dans java 5. Je pense que cela est recommandé maintenant plutôt que d’attendre / notifier, ce qui peut devenir assez compliqué. Je l’ai utilisé et ça marche bien.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

Au lieu d’utiliser ArrayList, vous pouvez utiliser une collection Concurrent, par exemple, ArrayBlockingQueue

 ArrayBlockingQueue theQueue; while(true) { YourObject o = theQueue.take(); //process your object } 

À l’autre endroit, où vous remplissez votre file d’attente, il vous suffit de faire une

 theQueue.add(theElement); 

Le thread qui attend des objects “dormira” jusqu’à ce qu’il y ait un élément. La méthode add réveillera le thread consommant.

Vous pouvez en savoir plus sur cette classe ici: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html

java.lang.ArrayList n’est pas du tout thread-safe. Pour faire la queue, il est bon d’utiliser BlockingQueue . Il bloque l’appel de thread si la queue est vide sans consumr de processeur. Vous pouvez utiliser ArrayBlockingQueue ou LinkedBlockingQueue ou une autre implémentation de la queue en fonction de vos besoins.

Même si vous pouvez l’implémenter avec wait and notifyAll il est toujours recommandé d’utiliser BlockingQueue .

Sans sumil, vos threads vont se mettre en boucle aussi vite qu’ils le peuvent et accéder à ArrayList, probablement la plupart du temps sans aucun résultat.

Je recommande de mettre en œuvre un modèle d’écoute / observateur. Si vous le pouvez, demandez au producteur qui remplit le tableau ArrayList de notifier les threads appropriés sur les modifications. Ainsi, vous passeriez d’un comportement d’interrogation à un comportement de type push.

Vous ne savez pas si cela est faisable dans votre architecture, mais des explications supplémentaires sur votre système sont nécessaires.

Qu’est-ce que le sondage et quels sont les problèmes?

Le processus de test d’une condition à plusieurs resockets jusqu’à ce qu’il devienne vrai est appelé interrogation.

L’interrogation est généralement mise en œuvre à l’aide de boucles pour vérifier si une condition particulière est vraie ou non. Si c’est vrai, certaines mesures sont sockets. Cela gaspille beaucoup de cycles CPU et rend la mise en œuvre inefficace. Par exemple, dans un problème de queue classique dans lequel un thread produit des données et un autre les consum.

Comment le multi-thread Java aborde-t-il ce problème?

Pour éviter les interrogations, Java utilise trois méthodes, à savoir wait() , notify() et notifyAll() .

Toutes ces méthodes appartiennent à la classe Object pour que toutes les classes les aient. Ils doivent être utilisés dans un bloc synchronisé uniquement.

wait () -Il indique au thread appelant d’abandonner le verrou et de s’endormir jusqu’à ce qu’un autre thread entre dans le même moniteur et appelle notify() .

notify () -Il réveille un seul thread qui a appelé wait() sur le même object. Il convient de noter que l’appel de notify() n’abandonne pas réellement le locking d’une ressource.

notifyAll () -Il réveille tous les threads ayant appelé wait() sur le même object.

ArrayList n’est pas une collection thread-safe. Utilisez ArrayBlockingQueue .

Classe ArrayBlockingQueue