2010-06-29 6 views
4

J'ai quelque chose comme ceci:Comment connaître la valeur qui a été associée à une entrée supprimée dans une WeakHashMap

private Map<MyObj1, MyObj2> map = new WeakHashMap<MyObj1, MyObj2>(); 

... somewhere in the code ... 
MyObj1 myObj1 = new MyObj1(); 
map.put(myObj1, new MyObj2(); 
... 
myObj1 = null; 

... somewhere else in a thread ... (I would like to pass to a checkThis(MyObj2) method the Value associated with the entry that was removed from the Map) 
/* something like this maybe */ 
while (true) { 
    MyObj2 myObj2 = referenceQueue.remove().get(); 
    checkThis(myObj2); 
} 

MyObj1 clé peut être retirée lorsque GC entre en jeu et il n'y a pas de référence forte à ce .

Je voudrais passer à checkThis(MyObj2) l'objet de valeur carte particulière associée à la clé qui a été supprimé (vérification peut-être un ReferenceQueue?)

Je ne peux pas comprendre comment mettre cela en code.

+0

Je mis à jour ma réponse avec une solution possible si vous êtes à la recherche encore. –

Répondre

0

Le vrai problème à propos de ce que vous voulez faire est qu'un WeakHashMap repose sur le garbage collector pour libérer des éléments inutilisés.

Puisque le GC fera son travail quand il veut sans aucun respect pour ce que vous faites, il sera difficile de suivre les changements sur le hashmap. En fait, ce que vous dites

« clé MyObj1 est supprimé quand il n'y a pas de référence forte à ce »

n'est pas exact. MyObj1 est libre d'être publié par le GC s'il n'a pas de refs autour, mais s'il n'est pas nécessaire de le libérer, il ne sera tout simplement pas publié.

+0

vous avez raison Jack, désolé j'ai mal exprimé ma question – mickthompson

0

Dans le préambule WeakHashMap (italique ajouté):

Une mise en œuvre de la carte en fonction Hashtable avec des clés faibles. Une entrée dans un WeakHashMap sera automatiquement supprimée lorsque sa clé n'est plus utilisée normalement. Plus précisément, la présence d'un mappage pour une clé donnée n'empêchera pas la clé d'être rejetée par le ramasse-miettes, c'est-à-dire rendue définissable, finalisée, puis récupérée. Lorsqu'une clé a été supprimée, son entrée est effectivement supprimée de la carte. Cette classe se comporte donc différemment des autres implémentations de Map.

Cependant, vous n'êtes jamais dit le WeakHashMap quand il « perd » un :-) d'entrée Si vous voulez uniquement sur les touches-à-un-instance à temps particulier, vous pouvez alors utiliser un scan de la carte (aussi seulement pratique pour certains n). Sinon, allez avec votre intuition à propos de ReferenceQueue.

Ce lien peut être utile: Java Reference Objects

0

files d'attente de référence

Une fois qu'un WeakReference commence à renvoyer null, l'objet, il a souligné est devenu ordures et l'objet WeakReference est à peu près inutile. Cela signifie généralement qu'une sorte de nettoyage est nécessaire; WeakHashMap, par exemple, doit supprimer ces entrées défuntes pour éviter de conserver un nombre toujours croissant de WeakReferences mortes.

La classe ReferenceQueue facilite le suivi des références manquantes. Si vous transmettez un ReferenceQueue dans le constructeur d'une référence faible, l'objet de référence sera automatiquement inséré dans la file d'attente de référence lorsque l'objet vers lequel il pointe est vide. Vous pouvez ensuite, à intervalles réguliers, traiter ReferenceQueue et effectuer le nettoyage nécessaire pour les références mortes.

See this page pour un tutoriel sur l'utilisation.

Pourriez-vous s'il vous plaît indiquer pourquoi vous utilisez ce site? Il y a très peu d'utilisations valables.
-à-dire un cache n'est pas une utilisation valide (ou du moins pas un bon)

Edit:

Ce code est équivalent à l'aide d'un WeakHashMap mais vous devez faire explicitement pour établir une corrélation entre la file d'attente avec le carte.

HashMap aHashMap = new HashMap(); 
ReferenceQueue Queue = new ReferenceQueue(); 
MyWeakReference RefKey = new MyWeakReference(key, Queue); 
aHashMap.put(RefKey, value); 
+0

Merci pour votre réponse. Je voudrais savoir quel était l'objet Value associé à l'entrée Key-Value qui a été supprimée d'un WeakHashMap. Une sorte d'EventListener du WeakHashMap remove() qui contiendra un appel à quelque chose comme processRemovedValue (value) (J'ai utilisé checkThis (MyObj2) dans ma question mise à jour) – mickthompson

+0

@mickthompson Vous devez continuer à interroger la file d'attente, vous ne serez pas averti . Je me demande toujours pourquoi vous essayez de mettre en œuvre cela. Si quelqu'un doit venir derrière vous, alors ce sera un cauchemar pour eux, c'est une partie très obscure de la langue/API. –

+0

comme dans mon exemple ci-dessus je continue d'interroger la file d'attente dans un fil .. mais même si quelque chose est retiré de WeakHashMap mon fil est toujours bloqué sur referenceQueue.remove(). Get() .. J'ai essayé de changer ma carte dans Map < WeakReference , MyObj2> mais cela n'a pas fonctionné – mickthompson

1

D'un commentaire sur une autre réponse:

Je veux qu'une fois que la session expire (et il n'y a aucune référence forte à cette session dans mon contexte App) la liste est réitérée et annuler est appelée sur tous les contrats à terme restants en attente d'exécution. Cette pour éviter d'avoir des travaux planifiés que s'exécutera même si la session utilisateur est a expiré.

Cela ressemble à un emploi pour une HttpSessionBindingListener

+0

Ceci n'est pas une réponse à la question d'origine . Mais pour le cas d'utilisation concret ici, c'est en effet une bien meilleure approche. De cette façon, les contrats à terme peuvent être annulés dès que la session expire, au lieu de se produire à un moment aléatoire, plus tard, lorsque la collecte des ordures se déclenche. –

Questions connexes