Ich habe einige Fragen zur Verwendung und Bedeutung der synchronized
Stichwort.
- Was ist die Bedeutung der
synchronized
Stichwort? - Wann sollten die Methoden
synchronized
? - Was bedeutet das programmatisch und logisch?
Ich habe einige Fragen zur Verwendung und Bedeutung der synchronized
Stichwort.
synchronized
Stichwort?synchronized
?Die synchronized
Schlüsselwort geht es um verschiedene Threads, die dieselben Variablen, Objekte und Ressourcen lesen und beschreiben. Dies ist kein triviales Thema in Java, aber hier ein Zitat von Sun:
synchronized
Methoden ermöglichen eine einfache Strategie zur Verhinderung von Thread Interferenzen und Speicherkonsistenz Fehler: Wenn ein Objekt für mehr als einen mehr als einen Thread sichtbar ist, werden alle Lese- oder Schreibvorgänge auf die Variablen dieses Objekts durch synchronisierte Methoden durchgeführt.
In einer sehr, sehr kleinen Nussschale: Wenn Sie zwei Threads haben, die dieselbe "Ressource" lesen und schreiben, beispielsweise eine Variable namens foo
müssen Sie sicherstellen, dass diese Threads atomar auf die Variable zugreifen. Ohne die synchronized
Schlüsselwort, sieht Ihr Thread 1 möglicherweise nicht die Änderung, die Thread 2 an foo
oder schlimmer noch, sie kann nur zur Hälfte geändert werden. Das wäre nicht das, was Sie logischerweise erwarten.
Auch hier handelt es sich um ein nicht triviales Thema in Java. Um mehr darüber zu erfahren, lesen Sie die Themen hier auf SO und im Internet:
Erforschen Sie diese Themen weiter, bis der Name "Brian Goetz" wird dauerhaft mit dem Begriff "Gleichzeitigkeit" in Ihrem Gehirn.
Nun, ich denke, wir haben genug von theoretischen Erklärungen, also betrachten Sie diesen Code
public class SOP {
public static void print(String s) {
System.out.println(s+"\n");
}
}
public class TestThread extends Thread {
String name;
TheDemo theDemo;
public TestThread(String name,TheDemo theDemo) {
this.theDemo = theDemo;
this.name = name;
start();
}
@Override
public void run() {
theDemo.test(name);
}
}
public class TheDemo {
public synchronized void test(String name) {
for(int i=0;i<10;i++) {
SOP.print(name + " :: "+i);
try{
Thread.sleep(500);
} catch (Exception e) {
SOP.print(e.getMessage());
}
}
}
public static void main(String[] args) {
TheDemo theDemo = new TheDemo();
new TestThread("THREAD 1",theDemo);
new TestThread("THREAD 2",theDemo);
new TestThread("THREAD 3",theDemo);
}
}
Anmerkung: synchronized
blockiert den Aufruf der Methode test() durch den nächsten Thread, solange die Ausführung des vorherigen Threads nicht beendet ist. Die Threads können jeweils einzeln auf diese Methode zugreifen. Ohne synchronized
können alle Threads gleichzeitig auf diese Methode zugreifen.
Wenn ein Thread die synchronisierte Methode 'test' des Objekts (hier ist das Objekt eine Instanz der Klasse 'TheDemo') aufruft, erwirbt er die Sperre dieses Objekts. Ein neuer Thread kann keine synchronisierte Methode desselben Objekts aufrufen, solange der vorherige Thread, der die Sperre erworben hatte, die Sperre nicht freigibt.
Ähnliches geschieht, wenn eine statische synchronisierte Methode der Klasse aufgerufen wird. Der Thread erwirbt die mit der Klasse verbundene Sperre (in diesem Fall kann jede nicht statische synchronisierte Methode einer Instanz dieser Klasse von einem beliebigen Thread aufgerufen werden, da die Sperre auf Objektebene noch verfügbar ist). Jeder andere Thread kann keine statische synchronisierte Methode der Klasse aufrufen, solange die Sperre auf Klassenebene nicht von dem Thread freigegeben wird, der die Sperre gerade hält.
Ausgang mit synchronisierter
THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
Ausgabe ohne Synchronisation
THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
Die synchronized
Schlüsselwort verhindert den gleichzeitigen Zugriff auf einen Codeblock oder ein Objekt durch mehrere Threads. Alle Methoden von Hashtable
sind synchronized
so dass jeweils nur ein Thread eine dieser Aufgaben ausführen kann.
Bei Verwendung von Nicht synchronized
Konstrukte wie HashMap
müssen Sie Thread-Sicherheitsfunktionen in Ihren Code einbauen, um Konsistenzfehler zu vermeiden.
synchronized
bedeutet, dass in einer Umgebung mit mehreren Threads ein Objekt mit synchronized
Methode(n)/Block(s) lässt nicht zu, dass zwei Threads auf die synchronized
Methode(n)/Block(s) von Code zur gleichen Zeit. Dies bedeutet, dass ein Thread nicht lesen kann, während ein anderer Thread ihn aktualisiert.
Der zweite Thread wird stattdessen warten, bis der erste Thread seine Ausführung beendet hat. Der Overhead ist die Geschwindigkeit, aber der Vorteil ist die garantierte Konsistenz der Daten.
Wenn Ihre Anwendung jedoch nur einen Thread hat, synchronized
Blöcke bieten keine Vorteile.
Die synchronized
Schlüsselwort bewirkt, dass ein Thread beim Eintritt in die Methode eine Sperre erhält, so dass nur ein Thread die Methode gleichzeitig ausführen kann (für die gegebene Objektinstanz, sofern es sich nicht um eine statische Methode handelt).
Dies wird häufig als "thread-safe" bezeichnet, aber ich würde sagen, dies ist ein Euphemismus. Es ist zwar richtig, dass die Synchronisierung den internen Zustand des Vektors vor Beschädigung schützt, aber das hilft dem Benutzer von Vector normalerweise nicht viel.
Bedenken Sie dies:
if (vector.isEmpty()){
vector.add(data);
}
Obwohl die beteiligten Methoden synchronisiert sind, können zwei unglücklich getaktete Threads einen Vektor mit zwei Elementen erstellen, da sie einzeln gesperrt und entsperrt werden.
Sie müssen also auch in Ihrem Anwendungscode synchronisieren.
Da die Synchronisierung auf Methodenebene a) teuer ist, wenn man sie nicht braucht, und b) unzureichend ist, wenn man sie braucht, gibt es jetzt unsynchronisierte Ersetzungen (ArrayList im Fall von Vector).
Kürzlich wurde das Concurrency-Paket veröffentlicht, das eine Reihe von cleveren Dienstprogrammen enthält, die sich um Multi-Threading-Probleme kümmern.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
19 Stimmen
download.oracle.com/javase/tutorial/essential/concurrency/
1 Stimmen
Hilfreiche Diskussion zwischen hashmap und hashtable und Synchronisierung: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
2 Stimmen
Mögliches Duplikat von Wie funktioniert die Synchronisation in Java?
2 Stimmen
Ich habe den gesamten Dokumentationslink vom ersten Kommentar an durchgelesen und erst im letzten Absatz verstanden. Anstatt Links einzufügen und nichts zu zitieren, ist es vielleicht hilfreicher, Links einzufügen und ein Zitat hinzuzufügen.
1 Stimmen
Ich hatte vor 3 Jahren eine Antwort geschrieben und Stackoverflow hat meine Frage fälschlicherweise gelöscht, da ich keine Copyrights von Github angegeben habe :) Völlig falsch, ich erinnere mich an die Antwort von der Universität und schrieb sie mit meinen eigenen Worten. Woher wissen Sie, dass Github-Benutzer nicht kopiert, dass von mir geniuses?