singleton avec volatile en Java
class MyClass
{
private static volatile Resource resource;
public static Resource getInstance()
{
if(resource == null)
resource = new Resource();
return resource;
}
}
Ici mon doute est selon la java de la simultanéité dans la pratique si vous utilisez volatile, coffre-fort à la publication qui se passe (c'est à dire dès que la référence est visible à un autre thread de données est également disponible). Donc, puis-je l'utiliser ici? Mais si elle est correcte, alors supposons que thread1 vérifie maintenant les "ressources" et c'est null si il commence la création de l'objet. Alors que thread1 est la création de l'objet, un autre thread, c'est à dire thread2 vient et de vérifier la valeur de la "ressource" et thread2 trouve nulle (on suppose la création de la "ressource" de l'objet prend un peu de temps considérable et que thread1 n'a pas encore achevé la création pour la sécurité de la publication n'est pas arrivé donc inaccessible thread2 )puis il va également commencer la création de l'objet? si oui, alors la classe de l'invariant de pauses. Suis-je la corriger? Merci de m'aider dans la compréhension de ce surtout l'utilisation de la volatilité ici.
source d'informationauteur Trying
Vous devez vous connecter pour publier un commentaire.
volatils résout un problème qui est visibilité . Si vous écrivez à une seule variable qui est déclarée volatils alors la valeur sera visible par les autres thread immédiatement. Comme nous le savons tous, nous avons différents niveaux de cache en os L1, L2, L3 et si nous écrire à une variable dans un thread, il n'est pas garanti d'être visible pour les autres, donc si l'on utilise volatile, il écrit direct à la mémoire et est visible pour les autres. Mais instable ne permet pas de résoudre la question de la atomicité c'est à dire
int a; a++;
n'est pas sûr. COMME il y a trois instructions machine associée.Vous avez raison, plusieurs threads peuvent essayer de créer un objet de la Ressource. Volatile seulement garantit que si un thread mises à jour de la référence, toutes les autres threads de voir la nouvelle référence, et non de mise en cache de référence. C'est plus lent, mais plus sûr.
Si vous n'avez besoin que d'une seule ressource qui n'est pas chargé, vous avez besoin de faire quelque chose comme ceci:
Je sais que vous ne vous posez pas de meilleures solutions, mais c'est certainement la peine si vous êtes à la recherche pour un paresseux singleton solution.
Utiliser une private static de la classe à charger le singleton. La classe n'est pas chargé jusqu'à ce que l'invocation et donc la référence n'est pas chargé jusqu'à ce que la classe est. Chargement de classe par la mise en œuvre est thread-safe et vous aussi vous engager très peu de frais généraux (dans le cas où vous faites répétitif volatile des charges [qui peut toujours être bon marché], cette résolution toujours aux charges normales après la construction initiale).
Je pense que vous devriez utiliser
syncronized
mot-clé avant degetInstance
définition.Pour de meilleures performances, vous pouvez utiliser vérifié en Double verrouillage modèle:
Lorsqu'il est appliqué à un champ, la Java volatils garantit que:
Plus info.
Vous avez raison, dans ce cas, la Ressource peut être construit à deux reprises en raison de la race que vous décrivez. Si vous souhaitez implémenter un singleton (sans verrouillage explicite) dans Java 5+, utiliser un enum singleton comme décrit dans les réponses à la Ce qui est un moyen efficace de mettre en œuvre un pattern singleton en Java?.
volatile
mot-clé garantit que lire et à écrire à cette variable sont atomiques.Selon la tutoriel
tout d'abord, avoir un Singleton de cette façon, vous êtes essentiellement la création d'un objet global qui est une mauvaise pratique. Je pense que vous utiliser les Énumérations à la place.
Voici ma suggestion pour ajouter volatils & concert.
Remarque: nous avons encore à faire vérifier.