Claire instance du Singleton en Java
J'ai une classe Singleton pour enregistrer l'état d'une application module.
Cette classe n'ont tout simplement beaucoup de variables de classe avec les setters et getters :
public class ModuleState{
private static ModuleState instance;
private A a;
private B b;
private C c;
..
..
..
..
private ModuleState (){}
public ModuleState getInstance(){
if(instance==null)
instance=new ModuleState();
return instance;
}
}
À un moment précis de la vie de l'application, j'ai le besoin d'EFFACER le module de l'état. Ce que je fais maintenant est de réinitialiser TOUTES les variables dans ModuleState par un clearAll() la méthode comme ceci:
public void clearAll(){
a=null;
b=null;
c=null;
..
..
}
Ma question est la suivante : il y a une méthode plus propre pour faire ce reset? Éventuellement de compensation de l'instance du singleton lui-même, sans remise à zéro à chaque variable de classe?
Le problème avec cette approche est que je peut avoir besoin d'ajouter une nouvelle variable de classe à la ModuleState. Dans ce cas, je dois me rappeler d'ajouter une ligne dans le clearAll() méthode pour réinitialiser la nouvelle variable.
OriginalL'auteur Nameless | 2013-05-12
Vous devez vous connecter pour publier un commentaire.
Ce sujet ...
p.s.: conformément à la discussion ci-dessous: dans un environnement multithread, il est très important de synchroniser l'accès sur l'instance parce que la JVM est autorisé à cache sa valeur. Vous pouvez utiliser
volatile
comme indiqué ci-dessus. Merci à tous!Cheers!
Oui, vous avez raison: c'est un peu contre l'idée d'un Singleton. En outre, il pourrait être nécessaire de synchroniser cette méthode. Mais encore fonctionnelle, n'est-ce pas?
Il cache quelque sorte. Juste appeler ModuleState.getInstance().getA().getFoo() a une chance d'accéder à un état de l'état, si un autre thread modifie le singleton en parallèle. Faire getInstance() synchronisé ne change rien.
Le même argument de l'insécurité pouvez ensuite appliquer à différents objets retournés par
getA..Z
, si évidemment certaines limites pratiques de "précision" doit être accepté. Faireinstance
volatils et l'utilisation de cette approche est probablement une solution décente pour l'OP du problème.La seule en fin de compte solution sûre est une grande classe qui n'a jamais expose tout de
A..Z
objets, mais ne peut être interrogé pour la feuille atomique valeurs qu'ils détiennent. L'ensemble de la classe devrait êtresynchronized
de sorte que le reset opération est mutuellement exclusive avec chaque get.OriginalL'auteur Trinimon
non, cette approche est tout à fait acceptable. vous êtes bien sûr de synchronisation d'accès à ces objets d'état d'une certaine façon, non? sinon vous risquez de vous quelqu'un de voir un demi-effacé objet de config.
une autre chose que vous pourriez faire à l'avenir contre toute surcharge de l'état ajoutées dans le futur est de stocker l'ensemble de votre état dans une table de hachage, par exemple, au lieu de champs individuels. de cette façon, clear()ing la table de hachage garantit que tout l'état est effacé et l'ajout supplémentaire de l'état dans l'avenir devient plus sûr
OriginalL'auteur radai
Vous avez besoin pour maintenir la même instance d'objet, afin de respecter le pattern Singleton, de sorte que votre approche est logique: la modification de la les membres.
Cependant, si vous souhaitez nettoyer un peu, pourquoi ne pas simplement avoir une liste interne, comme:
Une autre Option serait d'avoir un
HashMap
, qui lie le mot-clé le membre.Pour un
ArrayList
ou unHashMap
, leclearAll
méthode pourrait ressembler à ceci:Cette méthode n'aurez pas besoin de changer.
OriginalL'auteur christopher
Peut-être cela peut vous aider:
OriginalL'auteur gluckonavt
Faire un intérieur de classe pour tenir les champs, puis remplacer que exemple lorsque vous souhaitez réinitialiser. L'écrire dans le champ d'apporter une modification à tous les trois champs essentiellement atomique.
Par ailleurs, votre null vérification du code d'initialisation n'était pas thread-safe. J'ai corrigé aussi.
Noter que pour faire ce travail, vous devez en faire la référence à
values
volatils et de synchroniser tous les accès à elle, sinon (en raison de la java du modèle de mémoire) autres threads que celui qui appelle reset() peut voir l'ancienne référence.En fait, il ne permet pas d'obtenir quelque chose de plus que l'approche la plus simple, elle permet tout simplement le client pour mettre en cache le "singleton". Mais il n'y a pas de valeur intrinsèque à avoir ce genre de protocole: quel est le problème avec insistant sur le fait que le singleton toujours être acquis à partir de
getInstance
?merci pour le thread-safe fix
As-tu veux dire quand tu parles de "un énorme de classe qui n'a jamais expose tout de A..Z des objets, mais ne peut être interrogé pour la feuille atomique valeurs qu'ils détiennent. L'ensemble de la classe doivent être synchronisés, de sorte que l'opération de réinitialisation est mutuellement exclusive avec chacun" ? Par la façon dont je tiens cette solution, tout à la baisse? Est-il sécuritaire?
OriginalL'auteur Bohemian