12
votes

Meilleure façon de synchroniser la tâche asynchrone

Mon problème: J'ai 802.15.4 Réseau sans fil connecté à un port série (à l'aide d'une enveloppe). Je peux envoyer des packages dans le réseau et écouter les forfaits entrants. Comme vous pouvez l'imaginer, cela est très asynchrone.

Voici la tâche: je souhaite envoyer des commandes au réseau et attendre la réponse dans un appel de fonction. Par exemple: je veux obtenir la température du nœud avec l'ID de réseau 1338. P>

double getTemperature(int id) throws Exception { .... }


1 commentaires

D'ACCORD. Cette question pointe davantage dans la direction de "Y a-t-il un problème de java cool résoudre ce problème?"


3 Réponses :


1
votes

La meilleure façon est de terminer dans une classe de demande / de réponse réutilisable. De cette façon, vous pouvez avoir un moyen standard d'interroger le port série et d'attendre une réponse. Cette classe devra toutefois utiliser sans aucun doute utiliser le mot-clé synchronisé et attendre et notifier des commandes quelque part dans sa mise en œuvre. C'est un élément clé de l'écriture de Java et il est important de comprendre comment ils fonctionnent.

Si vous deviez concevoir une fonction comme vous dites, vous devez vous assurer que vous l'appelez à partir d'un fil pouvant bloquer en attente du résultat. La fonction devra mettre en œuvre une sorte de boucle d'attente à l'intérieur d'attendre la réponse du port série. Il est donc important que quel que soit le fil qu'il coure soit capable d'attendre également.

Cela soulève également un point supplémentaire. Si vous avez plusieurs threads faisant cela, vous devrez avoir une classe qui gère la communication de ports série pouvant traiter de plusieurs demandes provenant de plusieurs threads et de la file d'attente si nécessaire pour gérer la nature asynchrone du port série et le périphérique spécifique. à quoi vous vous connectez. Par exemple, il peut ne pas être approprié d'envoyer une deuxième commande avant que la réponse du premier est réelle complètement.

Il y a plusieurs problèmes compliqués ici, et il est important d'avoir un bon design en place qui les concerne tous de manière raisonnable.


1 commentaires

Merci pour votre participation. Cela me ramène au stylo et au papier :)



2
votes

Je ne suis pas sûr de comprendre la question correctée, mais j'utilise habituellement un futur pour ces sortes de tâches.

interne the futur Mise en œuvre utilise attendre et notifier Et tout cela, mais l'interface elle-même devient plutôt propre. xxx

dans votre code de communication, vous pouvez alors planer des messages entrants vers des futurs non remplis. Si la commande est garantie, vous pouvez faire quelque chose comme xxx

où myFutureImpl est une mise en œuvre future très fondamentale. Je suppose qu'il y a un fil de communication qui appelle réponse () quand un paquet est reçu. Je suppose également que le SerialIzeantDend () -fonction gère l'écriture sur le client ou les blocs jusqu'à ce que l'opération d'écriture puisse être faite ou remise à un fil de communication.

Le L'utilisation de structures de carte et de file d'attente de la concurrence peut rendre une synchronisation s inutile. S'il n'y a jamais un seul appel exceptionnel par identifiant, la file d'attente devient inutile bien sûr.


0 commentaires

7
votes

Vous pouvez le faire avec un blocageQueue afin de ne pas avoir à gérer manuellement aucune de la synchronisation. La demande peut envoyer le message, puis appeler prise () sur un blocageQueue qui attendra qu'un élément soit présent. L'élément est la réponse qui est insérée dans la file d'attente par n'importe quel auditeur que vous avez sur le port lorsque la réponse est renvoyée.

Il vous suffit de vous coordonner afin que l'auditeur et le demandeur partagent la même file d'attente. Vous n'avez besoin que d'une file d'attente de taille unique pour chaque demande de support de ce scénario. xxx


1 commentaires

C'est exactement la "chose spéciale java" que je cherchais!