2009-06-05 16 views
6

J'ai un mécanisme assez standard en Java pour résoudre le problème:Migration de concurrency Java concurrency Scala

  • Les éléments de travail doivent être programmés pour exécuter à un moment donné
  • Chaque élément de travail doit alors attendre une condition de devenir de véritables
  • Les éléments de travail devrait être résiliable

La solution que je l'utilise est comme suit:

  1. Avoir un programmateur mono-thread pour programmer mes éléments de travail
  2. Vous avez déjà un ExecutorService (qui peut être multi-thread)
  3. Chaque élément de travail prévu soumet ensuite le travail réel à l'ExecutorService. Le Future retourné est mis en cache dans une carte. Un service d'achèvement est utilisé pour enlever l'avenir du cache lorsque le travail est terminé
  4. Les articles peuvent être annulés par les futures mises en cache

Bien sûr, mon exécuteur testamentaire doit être au moins aussi grand que le nombre de bloquer les éléments de travail que je m'attends à avoir mais ce n'est pas un problème dans la pratique. Alors maintenant je suis en train de coder dans Scala et d'utiliser le framework d'acteur. En supposant que mon poste de travail peut être encapsulé dans un événement envoyé à un acteur:

  1. Quel mécanisme devrais-je utiliser pour programmer un poste de travail pendant un certain temps?
  2. Si un élément de travail est un événement envoyé à un acteur, comment puis-je m'assurer que le pool de threads de sauvegarde est plus grand que le nombre d'éléments pouvant bloquer simultanément
  3. Comment puis-je provoquer un travail planifié précédemment? article à annuler?
+0

Pouvez-vous expliquer ce que signifie «une condition qui devient vraie»? Est-ce cet état global? Est-ce I/O? – Apocalisp

+0

Je veux simplement dire que dans le cadre du travail, le processus pourrait devoir bloquer quelque chose (comme un fichier arrivant) –

Répondre

5

Quel mécanisme utiliser pour planifier un élément de travail pour une période spécifique?

J'utiliserais java.util.concurrent.ScheduledExecutorService.

Si un élément de travail est un événement envoyé à un acteur, comment puis-je vous assurer que le pool de threads de support est plus grand que le nombre d'éléments qui peuvent être bloquer en même temps

Cette grève moi comme un design qui va à l'encontre de l'effort de parallélisation. Essayez de minimiser ou d'éliminer le blocage et l'état global. Ce sont des obstacles à la composabilité et à l'évolutivité. Par exemple, pensez à avoir un seul thread dédié qui attend l'arrivée des fichiers, puis déclenche les événements vers les acteurs. Ou regardez java.nio pour les E/S asynchrones non bloquantes.

Je ne comprends pas entièrement vos exigences ici, mais il semble que vous pourriez avoir un seul thread/acteur à la recherche d'événements d'E/S. Ensuite, en tant que vos «éléments de travail» planifiés, planifiez les effets qui créent des acteurs non bloquants. Ces acteurs s'enregistrent-ils auprès du thread/acteur I/O pour recevoir des messages sur les événements d'E/S dont ils se soucient.

Comment puis-je annuler un élément de travail préalablement planifié?

ScheduledExecutorService renvoie Futures. Ce que vous avez n'est pas un mauvais design à cet égard. Collectez-les dans une carte et appelez future.cancel().

+0

Vous avez complètement raison de dire que le modèle de "blocage" est inapproprié et je serais à peu près le même conclusion moi-même, mais repoussait faire une réécriture complète. Cependant, j'ai finalement réussi à faire cela vendredi et maintenant j'ai un meilleur système –

1

Vous pouvez avoir un acteur de planification qui a une liste d'acteurs programmés, et utilise Actor.receiveWithin() pour se réveiller chaque seconde et envoyer des messages aux acteurs qui sont prêts à être exécutés. L'acteur de planification pourrait également gérer l'annulation. Une autre option consiste à laisser chaque acteur gérer sa propre planification directement avec receiveWithin(), au lieu de centraliser la planification.

Il y a une discussion sur ce problème dans le blog Simple cron like scheduler in Scala.