appels simultanés de singleton méthodes de la classe
J'ai une classe singleton:
public class Singleton {
private static Singleton istance = null;
private Singleton() {}
public synchronized static Singleton getSingleton() {
if (istance == null)
istance = new Singleton();
return istance;
}
public void work(){
for(int i=0; i<10000; i++){
Log.d("-----------", ""+i);
}
}
}
Et plusieurs Threads sont en appelant le travail() fonction:
public class Main {
public static void main(String[] args) {
new Thread (new Runnable(){
public void run(){
Singleton s = Singleton.getSingleton();
s.work();}
}).start();
System.out.println("main thread");
new Thread(new Runnable() {
public void run() {
Singleton s = Singleton.getSingleton();
s.work();
}
}).start();
}
}
J'ai remarqué que les deux Threads s'exécutant en même temps, comme si les deux fonctions ont été instancié dans le même temps.
Je veux le dernier thread à exécuter à la place de le thread précédent, plutôt que simultanément. Est-il possible en java pour faire l'appel de la deuxième remplacer l'espace de la mémoire du premier appel?
Je ne suis pas sûr de ce que votre question est de savoir, mais votre
J'ai essayé avec synchronisé, mais les deux fils sont toujours en cours d'exécution simultanément
retrait statique sur les deux fonctions() s'exécute en séquence, un à la fois. Apparemment, le deuxième appel est mis en attente après le premier appel. Comment peut le deuxième appel, il suffit d'exécuter à la place de la première?
getSingleton()
méthode doit être synchronized
work()
ne doit pas être statique, sinon l'exemple n'a pas de sensJ'ai essayé avec synchronisé, mais les deux fils sont toujours en cours d'exécution simultanément
retrait statique sur les deux fonctions() s'exécute en séquence, un à la fois. Apparemment, le deuxième appel est mis en attente après le premier appel. Comment peut le deuxième appel, il suffit d'exécuter à la place de la première?
synchronized
ne pas arrêter de les deux threads s'exécutant en même temps: il ne sérialiser leur accès à la getSingleton()
fonction. Dit autrement, cela signifie que vous pouvez être sûr que peu importe combien de threads sont actuellement dans l'exécution, un seul d'entre eux à la plupart seront d'exécution getSingleton()
à n'importe quel point dans le temps.OriginalL'auteur Luky | 2012-10-13
Vous devez vous connecter pour publier un commentaire.
Votre
getSingleton()
méthode est de tenter de paresseusement initialisation l'instance du SINGLETON, mais il a les problèmes suivants:synchronized
volatile
donc une condition de concurrence AMY cause de deux instances d'être créé.
Le meilleur et le plus simple a été en toute sécurité paresseusement initialiser un singleton sans de synchronisation est comme suit:
C'est thread-safe, parce que le contrat de la classe java chargeur est que toutes les classes ont leur initialisation statique complète avant de pouvoir être utilisés. Aussi, le chargeur de classes ne prend pas en charge une classe jusqu'à ce qu'il est référencé. Si deux threads appel
getSingleton()
simultanément, leHolder
classe sera toujours seulement obtenir chargés à la fois, et doncnew Singleton()
n'est exécutée qu'une fois.C'est toujours paresseux parce que le
Holder
classe est seulement référencé à partir degetSingleton()
méthode, de sorte que leHolder
classe sont chargés uniquement lorsque le premier appel àgetSingleton()
est faite.La synchronisation n'est pas nécessaire, parce que ce code s'appuie sur la classe du chargeur de synchronisation interne, qui est l'épreuve des balles.
Ce modèle de code est la seule façon de voler avec des singletons. Il est:
Les autres analogues de la structure du code (tout aussi sûre et rapide) est d'utiliser un
enum
avec un seul exemple, mais je trouve cela maladroit et l'intention est de moins en moins claires.synchronized
dans ce cas?oh oui - oublié de l'enlever (je copie-collé de l'original impl et modifié). Fixe maintenant. Thx.
OriginalL'auteur Bohemian
@Amit a déclaré dans un commentaire votre
getSingleton()
méthode doit êtresynchronized
. La raison pour cela est qu'il est possible pour plusieurs threads pour demander une instance dans le même temps et le premier thread sera toujours l'initialisation de l'objet et la référence sera nulle lorsque le thread suivant vérifie. Cela entraîne deux instances en cours de création.Marquage de votre méthode
synchronized
va l'amener à bloc et d'un seul thread à la fois de l'appeler. Cela devrait résoudre votre problème.getSingleton()
n'est pas efficace. Seuls les premiers appels àgetSingleton()
doivent être synchronisés pour s'assurer que l'instance a été initialisé et publié correctement.Cette question est de 5 ans et était plutôt vague. L'efficacité n'a jamais été mentionné. Si c'est simplement paresseusement instancier un singleton, le titulaire motif mentionné dans la réponse sommet est la façon correcte de le faire en contournant la synchronisation entièrement.
OriginalL'auteur Jim Mitchener
Utiliser
synchronized
sur la méthode deou, tout simplement, utiliser une finale privée de l'initialiseur (instanciation va se passer à la classe-temps de chargement)
OriginalL'auteur CAFxX
Ressources titulaire donnée en Java de la Simultanéité Dans la Pratique:http://www.javaconcurrencyinpractice.com/ est le meilleur non bloquant le pattern singleton disponibles. Le singleton est initialisées (les deux SingletonHolder et classe Singleton est chargé au Moment de l'Exécution lorsque la méthode getInstance() est appelée la première fois) et de l'accès ou de la méthode est non-bloquante.
}
OriginalL'auteur clinton
Je suis venu avec ce code qui est en train de faire à peu près ce que j'avais besoin.
L'orignal question était "Est possible d'effectuer les opérations suivantes sans l'aide de threads? Mais plutôt, en manipulant directement la mémoire avec la langue?" Si la réponse est non, peut-être que vous pouvez m'aider à améliorer les suivantes:
Ce code est utile pour "anti-rebond" les appels multiples à un auditeur, d'un tir en rafale sur les entrées de l'utilisateur.
Il a les inconvénients qu'il utilise une fonction de veille. Le temps de sommeil devrait être suffisamment élevée pour empêcher les événements dans un éclat de lancer l'exécution de la tâche qui prend du temps (seul le dernier événement). Malheureusement, il n'existe aucune garantie que cela peut toujours arriver, même pour un grand moment de sommeil.
OriginalL'auteur Luky
Vous pouvez utiliser des Verrous autour de ressources partagées. Utiliser le
Reentrant
classe. Il empêche des conditions de course pour plusieurs threads.OriginalL'auteur Jainam Shah