Pattern pour instanciation singleton paresseux thread-safe en Java
le paresseux thread-safe singleton instantion est un peu pas facile à comprendre pour chaque codeur, j'ai donc voulu créer une classe dans notre entreprise, cadre pour faire le travail.
Qu'en pensez-vous? Voyez-vous quelque chose de mauvais? Est-il quelque chose de similaire, comme dans Apache Commons? Comment puis-je faire mieux?
Supplier.java
public interface Supplier<T> {
public T get();
}
LazyThreadSafeInstantiator.java
public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
private final Supplier<T> instanceSupplier;
private volatile T obj;
public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
@Override
//http://en.wikipedia.org/wiki/Double-checked_locking
public T get() {
T result = obj; //Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
if (result == null) {
synchronized(this) {
result = obj;
if (result == null) {
result = instanceSupplier.get();
obj = result;
}
}
}
return result;
}
}
Exemple d'utilisation:
public class Singleton1 {
private static final Supplier<Singleton1> instanceHolder =
new LazyThreadSafeInstantiator<Singleton1>(new Supplier<Singleton1>() {
@Override
public Singleton1 get() {
return new Singleton1();
}
});
public Singleton1 instance() {
return instanceHolder.get();
}
private Singleton1() {
System.out.println("Singleton1 instantiated");
}
}
Grâce
source d'informationauteur Igor Mukhin
Vous devez vous connecter pour publier un commentaire.
Non, c'est vraiment très, très simple:
Mieux encore, faire un enum:
C'est thread-safe, et il est paresseux (l'initialisation se passe en classe, le temps de chargement, et Java ne permet pas de charger des classes jusqu'à ce qu'ils sont au premier).
Fait est que 99% du temps, vous n'avez pas besoin d'un chargement différé à tous les. Et de le 1% restant, dans 0,9% de la ci-dessus est parfaitement paresseux assez.
Vous avez un profiler et a déterminé que votre application belings pour le 0,01% qui a vraiment besoin de lazy-loading-au-premier-accès? Ne crois pas. Alors, pourquoi perdez-vous votre temps à vous concocter ces Rube Goldbergesque code des abominations pour résoudre un non-problème existant?
Pour une version qui est plus lisible (à mon avis) que celui présenté dans la question, on peut se référer à la Initialisation à la Demande du Titulaire de l'idiomeintroduit par le projet de Loi Pugh. Non seulement il est thread-safe, compte tenu de la Java 5 modèle de mémoire, le singleton est également initialisées.
Semble overengineered pour moi.
Je ne vois vraiment pas comment le fait d'avoir helper classe aide.
Tout d'abord, c'est à l'aide de double-verrouillage idiome, et il a été prouvé une fois et de nouveau cassé.
Deuxième, si vous ONT POUR utilisation d'un singleton, pourquoi ne pas initialiser
static final
instance.Ce code est thread-safe et a été prouvée à travailler.
Vérifier Vineet Reynolds réponse lorsque vous avez besoin d'initialiser l'instance du singleton sur une première obtenir. Dans de nombreux cas, je pense que cette approche est trop.
N'est pas la double vérification de verrouillage du motif et de l'utilisation de la volatilité des cassé sur les compilateurs JIT et multi-core/processeur systèmes en raison de la Java du Modèle de Mémoire & possibilité de sortir de l'exécution des ordres?
Plus généralement, il semble qu'un cadre pour les singletons est overkill pour ce qui est essentiellement un joli modèle simple à mettre en œuvre correctement.
Je suis d'accord avec d'autres affiches et de dire qu'il ne sembler un peu exagéré, mais ont dit que je pense que c'est quelque chose que développeur junior est susceptible de se tromper. Je pense que, parce que le comportement du fournisseur qui construit le singleton (voir ci-dessous) est la même dans presque tous les cas, je serais tenté de mettre ce que le comportement par défaut dans le
LazyThreadSafeInstantiator
. L'utilisation de la annonomous intérieur de la classe à chaque fois que vous souhaitez utiliser un singleton est vraiment salissant.Ce qui pourrait être fait en fournissant une surcharge du constructeur qui prend la Classe singleton nécessaire.
Ce serait alors utilisé comme.
C'est à mon avis est un peu plus propre. Vous pourriez alos étendre cette suite à l'utilisation des arguments du constructeur.
sauf peut-être le premier get() dans un thread, tous get() appels nécessitent pas de synchronisation ou de lecture volatile. l'objectif d'origine de la double vérification de verrouillage est réalisé.