gleichzeitige Aufrufe von singleton-Klassen-Methoden
Habe ich eine singleton-Klasse:
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);
}
}
}
Und mehrere Threads den Aufruf der work () - Funktion:
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();
}
}
Bemerkte ich, das zwei Threads gleichzeitig ausgeführt werden, als wenn zwei arbeiten Funktionen instanziiert wurden bei der gleichen Zeit.
Möchte ich den letzten thread ausgeführt werden, an die Stelle der früheren thread, dann eher gleichzeitig. Ist es möglich in java, um den zweiten Anruf überschreiben der Speicher-Platz der erste Anruf?
Ich bin mir nicht sicher, was deine Frage ist, aber Ihre
Ich habe versucht mit synchronisiert, aber die beiden threads sind immer noch die gleichzeitig ausgeführt
entfernen statischer die beiden arbeiten () - Funktionen läuft in der Reihenfolge, ein zu einer Zeit. Anscheinend ist der zweite Aufruf in die Warteschlange gestellt, nach dem ersten Aufruf. Wie können Sie den zweiten Anruf führen Sie einfach statt der ersten?
getSingleton()
Methode sollte synchronized
work()
sollte nicht statisch sein, da sonst das Beispiel nicht sinnvollIch habe versucht mit synchronisiert, aber die beiden threads sind immer noch die gleichzeitig ausgeführt
entfernen statischer die beiden arbeiten () - Funktionen läuft in der Reihenfolge, ein zu einer Zeit. Anscheinend ist der zweite Aufruf in die Warteschlange gestellt, nach dem ersten Aufruf. Wie können Sie den zweiten Anruf führen Sie einfach statt der ersten?
synchronized
nicht aufhören können zwei threads gleichzeitig ausgeführt: es wird nur serialisiert den Zugriff auf die getSingleton()
Funktion. Anders gesagt, es bedeutet, dass Sie können sicher sein, dass egal, wie viele threads sind derzeit in der Ausführung, nur einer von Ihnen am meisten wird die Ausführung getSingleton()
an jedem beliebigen Punkt in der Zeit.
InformationsquelleAutor Luky | 2012-10-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre
getSingleton()
Methode versucht, faul initialisieren die SINGLETON-Instanz, hat aber folgende Probleme:synchronized
volatile
so eine race-condition AMY dazu führen, dass zwei Instanzen erstellt werden.
Die besten und einfachsten war sicher zu faul initialisieren einer singleton - ohne Synchronisation ist wie folgt:
Dieser ist thread-safe, weil der Vertrag der java-class-loader ist, dass alle Klassen haben Ihre statische Initialisierung abgeschlossen ist, bevor Sie genutzt werden können. Auch der class-loader wird nicht geladen, eine Klasse, bis es auf die verwiesen wird. Wenn zwei thread-Aufruf
getSingleton()
gleichzeitig, dieHolder
Klasse wird nur noch einmal geladen, und damitnew Singleton()
wird nur einmal ausgeführt.Dies ist immer noch faul, weil die
Holder
Klasse ist nur aus verwiesengetSingleton()
- Methode, sodass dieHolder
Klasse nur geladen wird, wenn der erste AufrufgetSingleton()
gemacht wird.Synchronisierung ist nicht erforderlich, da dieser code beruht auf dem class loader auf ' s interne Synchronisation, das ist bullet proof.
Dieses code-Muster ist der einzige Weg, um zu Fliegen mit singletons. Es ist:
Der ähnliche code-Muster (ebenso sicher und schnell) ist die Verwendung eines
enum
mit einer einzigen Instanz, aber ich finde das ungeschickt und die Absicht ist weniger klar.synchronized
in diesem Fall?ach ja - habe vergessen, es zu entfernen (ich kopieren / eingefügt, die original-impl und modifiziert wurde). Ist jetzt behoben. Thx.
InformationsquelleAutor Bohemian
Als @amit erklärte in einem Kommentar Ihre
getSingleton()
Methode solltesynchronized
. Der Grund dafür ist, dass es möglich ist, mehrere threads zu Fragen, für eine Instanz zur gleichen Zeit und der erste thread wird immer noch initialisiert das Objekt und die Referenz den Wert null, wenn der nächste thread überprüft. Dadurch werden zwei Instanzen erstellt werden.Kennzeichnung der Methode als
synchronized
dazu, dass es zu blockieren und erlauben nur ein thread zu einem Zeitpunkt zu nennen. Dies sollte Ihr problem lösen.getSingleton()
ist nicht effizient. Nur die ersten paar Anrufe zugetSingleton()
sollte synchronisiert werden, um sicherzustellen, dass die Instanz initialisiert wurde und richtig publiziert.Diese Frage ist 5 Jahre alt und war ziemlich vage. Die Effizienz wurde nie erwähnt. Wenn er bloß zu faul die Instanzierung eines Singletons dann den Halter Muster erwähnt in der top-Antwort ist die richtige Art und Weise, es zu tun, unter Umgehung der Synchronisation völlig.
InformationsquelleAutor Jim Mitchener
Entweder
synchronized
auf die factory-Methodeoder einfach eine private final-Initialisierer (Instanziierung geschehen am Klasse-load-time)
InformationsquelleAutor CAFxX
Ressource Halter in Java Concurrency In Practice:http://www.javaconcurrencyinpractice.com/ ist die beste non-blocking singleton-Muster zur Verfügung. Der singleton ist faul initialisiert (beide SingletonHolder und Singleton-Klasse wird zur Laufzeit geladen, wenn die getInstance () - Methode aufgerufen, die erste Zeit) und die Zugangs-oder die Methode ist nicht-blockierend.
}
InformationsquelleAutor clinton
Kam ich mit diesem code, dass ist schon ziemlich viel, was ich brauchte.
Die Original Frage war: "Ist Folgendes möglich ohne die Verwendung von threads? Sondern durch die direkte Manipulation der Speicher mit der Sprache?" Wenn die Antwort Nein ist, vielleicht können Sie mir helfen zu verbessern die folgenden:
Dieser code ist nützlich, um "debounce" mehrere Anrufe zu einem listener, feuerte eine Salve auf Eingaben des Benutzers.
Es hat die Nachteile, die es benutzt eine sleep-Funktion. Die Zeit schlafen sollte hoch genug sein, um zu verhindern, dass Ereignisse, die in einem burst zu Beginn der Durchführung der zeitaufwendigen Aufgabe (nur die Letzte Veranstaltung sollte). Leider gibt es keine Garantie, dass dies immer passieren kann, auch für eine große Schlaf-Zeit.
InformationsquelleAutor Luky
Können Sie Sperren, um die gemeinsam genutzten Ressourcen. Verwenden Sie die
Reentrant
Klasse. Es verhindert race conditions, die für mehrere threads.InformationsquelleAutor Jainam Shah