2009-03-11 4 views
2

Dans mon application, j'ai le modèle récurrent suivant où j'ai l'impression que c'est une version incomplète ou déformée d'un modèle commun que je ne connais pas. Dans ma mise en œuvre, je n'arrive pas à trouver un bon moyen de mettre en œuvre une opération particulière, comme décrit ci-dessous.Design Pattern pour Java: Cela vous semble-t-il familier?

Une collection d'objets, appelons-les "sources", produit des données si vous appelez une méthode sur eux. Une instance de ScheduledThreadPoolExecutor (de java.util.concurrent) est utilisé pour périodiquement faire des lectures sur les sources et mettre les données sur une file d'attente sortante commune:

 
--o 
     method calls +-----+ 
--o  <--   | o |  ---> ||||||||||| 
      -->   | o o | 
--o  data   +-----+ 

sources    thread pool   outbound queue 

Les sources, le pool de threads et la file d'attente font partie d'une classe qui fournit méthodes pour ajouter des sources et récupérer la tête de la file d'attente.

Voici le code pour ajouter une nouvelle source. Je me demande ce qui se passe si je supprime une source de la collection.

public void vAddSource(ISource src) 
{ 
    this._rgSources.add(src); 
    final ISource srcT = src; 
    // q is the outbound queue, which is a private member in the class 
    // defining this method. Name is abbreviated for readability 
    Runnable cmd = new Runnable() { public void run() { q.add(srcT.sRead()); } } 
    // tpx is the thread pool 
    this._tpx.scheduleAtFixedRate(cmd, 0L, 1000L, TimeUnit.MILLISECONDS); 
} 

Maintenant, la façon dont Java fonctionne - si je suis arrivé que correctement -, src, etc. sont des identificateurs d'objets qui se sont passés autour de la valeur, donc dans le code ci-dessus il n'y a qu'un seul objet ISource et un identifiant pour elle est ajouté à la collection ainsi que transmis dans le pool de threads. Si je supprime l'identificateur de la collection, l'objet est toujours là, par conséquent le pool de threads continuera à lire à partir de lui comme si rien ne s'était passé. Est-ce que je comprends bien cela? Et quelle serait une approche typique si vous vouliez que le pool de threads prenne note de la suppression et rejette également la source?

Répondre

3

ThreadPoolExecutor (et donc ScheduledThreadPoolExecutor) a une méthode remove(Runnable). Vous pouvez également être intéressé par FutureTask qui peut être annulé (bien que cela ne le sortira pas de la file d'attente de travail). ETA (par Hanno Fietz, de la réponse de pgras): Cela nécessite également de mapper les Runnables à une source afin que la méthode removeSource puisse appeler ThreadPoolExecutor.remove avec la bonne.

+0

Merci. Comme c'est évident, j'ai dû oublier cela. –

2

Une solution consisterait à conserver un mappage entre les sources et les exécutables afin que vous puissiez implémenter une méthode removeSource. Une autre solution consisterait à conserver un WeakReference à la source plutôt qu'un hard et à laisser le Runnable se terminer si la source était garbage collection.

0

Vous écrivez que vous n'êtes pas au courant du modèle. Le java.lang.Runnable() utilise le modèle de commande - un modèle de conception comportementale.