bon usage du singleton synchronisé?
Je pense à la construction d'un projet de loisirs, un hors genre de chose, juste pour rafraîchir mon de programmation/conception.
C'est essentiellement un multi threaded spider web, la mise à jour de la même structure de données objet->int.
De sorte qu'il est certainement exagéré pour utiliser une base de données pour cette, et la seule chose que je pouvais penser, c'est un "thread-safe" singleton utilisé pour contenir ma structure de données. http://web.archive.org/web/20121106190537/http://www.ibm.com/developerworks/java/library/j-dcl/index.html
Est-il une approche différente je devrais regarder dans?
source d'informationauteur Dan.StackOverflow
Vous devez vous connecter pour publier un commentaire.
Double-vérifier le verrouillage a été prouvé à être incorrect et erroné (du moins en Java). Faire une recherche ou de regarder Wikipedia inscription pour la raison exacte.
D'abord et avant tout est le programme de justesse. Si votre code n'est pas thread-safe (dans un environnement multi-thread), il est cassé. L'exactitude vient en premier avant d'optimisation de la performance.
Pour être correct, vous devrez synchroniser l'ensemble de
getInstance
méthodestatique ou initialiser
L'aide d'initialisation de la base de données dans un navigateur web est probablement pas la peine. L'initialisation tardive ajoute de la complexité et une vitesse de frappe. Un cas où il est justifié, c'est quand il ya une bonne chance que les données ne seront jamais nécessaire. Aussi, dans une application interactive, il peut être utilisé pour réduire le temps de démarrage et de donner la illusion de vitesse.
Pour un non-application interactive comme un web-crawler, qui sera sans doute besoin de sa base de données tout de suite, l'initialisation différée est un mauvais ajustement.
D'autre part, une web-crawler est facilement parallélisable, et bénéficieront grandement d'être multi-thread. En l'utilisant comme un exercice de maîtrise de la
java.util.concurrent
bibliothèque serait extrêmement utile. Plus précisément, regarderConcurrentHashMap
etConcurrentSkipListMap
, qui permettent à plusieurs threads de lire et mettre à jour une texture partagée.Lorsque vous vous débarrasser de l'initialisation tardive, le plus simple pattern Singleton est quelque chose comme ceci:
Le mot-clé
final
est la clé ici. Même si vous fournissez unstatic
"getter" pour le singleton plutôt que de permettre un accès direct aux champs, faire le singletonfinal
permet de s'assurer de l'exactitude et permet plus agressives d'optimisation par le compilateur JIT.Si votre vie en dépendait quelques microsecondes alors je vous conseille pour optimiser votre verrouillage de ressource d'où ça comptait.
Mais dans ce cas, le mot clé ici est de hobby!
Ce qui signifie que si vous avez synchronisé l'ensemble de la getInstance() méthode vous permettra d'être bien dans 99,9% de tous les cas. Je ne recommande PAS de le faire d'une autre façon.
Plus tard, si vous le prouver par le biais de profilage que le getInstance() la synchronisation est le goulot d'étranglement de votre projet, vous pouvez alors déplacer sur et optimiser la simultanéité. Mais je doute vraiment qu'il va vous causer des ennuis.
Jeach!
Essayer le le projet de Loi Pugh la solution de l'initialisation sur la demande du titulaire de l'idiome.
La solution la plus portable à travers les différents compilateurs Java et les machines virtuelles.
La solution est thread-safe, sans exiger spéciales les constructions de langage (c'est à dire volatil et/ou de synchronisation).
http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh
comme Joshua Bloch affirme dans son livre "effective java 2nd edition" je suis également d'accord qu'un seul élément d'un type enum est la meilleure façon de mettre en œuvre un singleton.
Si vous regardez tout en bas de cet article, vous allez voir la suggestion de simplement utiliser un champ statique. Ce serait mon inclination: vous n'avez pas vraiment besoin paresseux instanciation (si vous n'avez pas besoin
getInstance()
être à la fois un accesseur et une méthode de fabrique). Vous voulez juste pour s'assurer que vous en avez une et une seule de ces choses. Si vous avez vraiment besoin de l'accès global à une telle chose, je ne l'utiliserais que l'exemple de code vers le bas:Noter que le Singleton est maintenant construite lors de l'installation des champs statiques. Cela devrait fonctionner et pas face à l'enfilage des risques potentiellement mauvaise synchronisation des choses.
Tout ce que dit, peut-être que vous avez vraiment besoin est l'un des thread-safe structures de données disponibles dans le moderne Jdk. Par exemple, je suis un grand fan de la ConcurrentHashMap: la sécurité des threads plus je n'ai pas à écrire le code (FTW!).
Comment sur:
Pourquoi ne pas créer une structure de données que vous transmettez à chacun des fils que l'injection de dépendance. De cette façon, vous n'avez pas besoin d'un singleton. Vous avez encore besoin de faire le thread-safe.
L'article référencé ne parle que de la prise de la création de l'objet singleton, sans doute une collection, dans ce cas, le thread-safe. Vous avez également besoin d'un thread-safe collection de sorte que les opérations de collecte aussi fonctionner comme prévu. Assurez-vous que la collection sous-jacente dans le singleton est synchronisé, peut-être l'aide d'un ConcurrentHashMap.
Découvrez cet article La mise en œuvre de Singleton en C#