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
?Das Schlüsselwort Synchronized in Java hat mit der Thread-Sicherheit zu tun, d. h. wenn mehrere Threads dieselbe Variable lesen oder schreiben.
Dies kann direkt (durch Zugriff auf dieselbe Variable) oder indirekt (durch Verwendung einer Klasse, die eine andere Klasse verwendet, die auf dieselbe Variable zugreift) geschehen.
Das Schlüsselwort synchronized wird verwendet, um einen Codeblock zu definieren, in dem mehrere Threads auf sichere Weise auf dieselbe Variable zugreifen können.
Syntaktisch gesehen ist die synchronized
Schlüsselwort nimmt ein Object
als Parameter (genannt ein Sperrobjekt ), auf die dann ein { block of code }
.
Wenn die Ausführung auf dieses Schlüsselwort stößt, versucht der aktuelle Thread, das Schlüsselwort zu "sperren/erwerben/zu besitzen". Sperrobjekt und führen den zugehörigen Codeblock aus, nachdem die Sperre erlangt wurde.
Alle Schreibvorgänge auf Variablen innerhalb des synchronisierten Codeblocks sind garantiert für jeden anderen Thread sichtbar, der in ähnlicher Weise Code innerhalb eines synchronisierten Codeblocks ausführt und denselben Sperrobjekt .
Die Sperre kann jeweils nur von einem Thread gehalten werden, während der alle anderen Threads, die versuchen, dieselbe Sperre zu erhalten, die Sperre Sperrobjekt warten (pausieren ihre Ausführung). Die Sperre wird aufgehoben, wenn die Ausführung den synchronisierten Codeblock verlässt.
Hinzufügen von synchronized
Schlüsselwort zu einer Methodendefinition ist gleichbedeutend mit der Einbettung des gesamten Methodenkörpers in einen synchronisierten Codeblock mit dem Sperrobjekt unter this
(zum Beispiel Methoden) et ClassInQuestion.getClass()
(für Klassenmethoden) .
- Eine Instanzmethode ist eine Methode, die nicht über static
Stichwort.
- Eine Klassenmethode ist eine Methode, die static
Stichwort.
Ohne Synchronisierung ist nicht gewährleistet, in welcher Reihenfolge die Lese- und Schreibvorgänge stattfinden, so dass die Variable möglicherweise Müll enthält.
(Eine Variable könnte beispielsweise so enden, dass die Hälfte der Bits von einem Thread und die Hälfte der Bits von einem anderen Thread geschrieben wurde, so dass die Variable in einem Zustand zurückbleibt, den keiner der Threads zu schreiben versucht hat, sondern ein kombiniertes Durcheinander von beiden).
Es reicht nicht aus, einen Schreibvorgang in einem Thread abzuschließen, bevor (zur Wanduhrzeit) ein anderer Thread ihn liest, denn die Hardware könnte den Wert der Variablen zwischengespeichert haben, und der lesende Thread würde den zwischengespeicherten Wert anstelle des geschriebenen Wertes sehen.
Im Fall von Java müssen Sie also das Java Memory Model befolgen, um sicherzustellen, dass keine Threading-Fehler auftreten.
Mit anderen Worten: Benutzen Sie Synchronisation, atomare Operationen oder Klassen, die diese für Sie verwenden, unter der Haube.
Quellen
http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Java®-Sprachenspezifikation, 2015-02-13
Man kann es sich als eine Art Drehkreuz vorstellen, wie man es auf einem Fußballplatz finden kann. Es gibt parallele Ströme von Menschen, die hineinwollen, aber am Drehkreuz werden sie "synchronisiert". Es kann immer nur eine Person durchkommen. Alle, die durch wollen, kommen durch, aber sie müssen möglicherweise warten, bis sie durch können.
Was ist das Schlüsselwort "synchronized"?
Threads kommunizieren in erster Linie durch gemeinsamen Zugriff auf Felder und die Objekte, auf die sich Referenzfelder beziehen. Diese Form der Kommunikation ist äußerst effizient, macht aber zwei Arten von Fehlern möglich: Thread-Interferenz und Speicherkonsistenzfehler . Das Werkzeug, das zur Vermeidung dieser Fehler benötigt wird, ist die Synchronisierung.
Synchronisierte Blöcke oder Methoden verhindern Thread-Interferenzen und stellen sicher, dass die Daten konsistent sind. Zu jedem Zeitpunkt kann nur ein Thread auf einen synchronisierten Block oder eine synchronisierte Methode zugreifen ( kritischer Abschnitt ), indem er eine Sperre erwirbt. Andere Thread(s) warten auf die Freigabe der Sperre, um auf kritischer Abschnitt .
Wann werden Methoden synchronisiert?
Methoden werden synchronisiert, wenn Sie synchronized
zur Methodendefinition oder -deklaration. Sie können auch einen bestimmten Codeblock innerhalb einer Methode synchronisieren.
Was bedeutet das pro grammatikalisch und logisch?
Das bedeutet, dass nur ein Thread auf kritischer Abschnitt indem er ein Schloss erwirbt. Solange dieser Thread diese Sperre nicht freigibt, müssen alle anderen Threads darauf warten, eine Sperre zu erhalten. Sie haben keinen Zugriff auf die kritischer Abschnitt ohne den Erwerb der Sperre.
Das kann man nicht mit einem Zauber machen. Es liegt in der Verantwortung des Programmierers, die kritische(r) Abschnitt(e) in der Anwendung und bewahre sie entsprechend. Java bietet einen Rahmen, um Ihre Anwendung zu schützen, aber wo und welche Abschnitte geschützt werden müssen, liegt in der Verantwortung des Programmierers.
Weitere Details aus der Java-Dokumentation Seite
Intrinsische Sperren und Synchronisierung:
Die Synchronisierung basiert auf einer internen Einheit, die als intrinsische Sperre oder Monitorsperre bezeichnet wird. Intrinsische Sperren spielen bei beiden Aspekten der Synchronisierung eine Rolle: Erzwingen des exklusiven Zugriffs auf den Zustand eines Objekts und Herstellen von Vorher-Nachher-Beziehungen, die für die Sichtbarkeit wichtig sind.
Jedes Objekt ist mit einer eigenen Sperre versehen . Konventionell muss ein Thread, der exklusiven und konsistenten Zugriff auf die Felder eines Objekts benötigt, die intrinsische Sperre des Objekts erwerben, bevor er auf sie zugreift, und dann die intrinsische Sperre freigeben, wenn er mit ihnen fertig ist.
Ein Thread gilt als Eigentümer der intrinsischen Sperre zwischen dem Zeitpunkt, an dem er die Sperre erworben hat, und dem Zeitpunkt, an dem er die Sperre freigegeben hat. Solange ein Thread eine intrinsische Sperre besitzt, kann kein anderer Thread die gleiche Sperre erwerben. Der andere Thread wird blockiert, wenn er versucht, die Sperre zu erhalten.
Wenn ein Thread eine intrinsische Sperre freigibt, wird eine "happens-before"-Beziehung zwischen dieser Aktion und jedem nachfolgenden Erwerb der gleichen Sperre hergestellt.
Die Synchronisierung von Methoden hat zwei Vorteile Auswirkungen :
Erstens ist es nicht möglich, dass sich zwei Aufrufe von synchronisierten Methoden auf demselben Objekt überschneiden.
Wenn ein Thread eine synchronisierte Methode für ein Objekt ausführt, werden alle anderen Threads, die synchronisierte Methoden für dasselbe Objekt aufrufen, blockiert (die Ausführung wird ausgesetzt), bis der erste Thread mit dem Objekt fertig ist.
Zweitens: Wenn eine synchronisierte Methode beendet wird, stellt sie automatisch eine "happens-before"-Beziehung zu jedem nachfolgenden Aufruf einer synchronisierten Methode für dasselbe Objekt her.
Dadurch wird gewährleistet, dass Änderungen am Zustand des Objekts für alle Threads sichtbar sind.
Suchen Sie nach anderen Alternativen zu Synchronisation in :
Synchronized normal method
gleichbedeutend mit Synchronized statement
(verwenden Sie dies)
class A {
public synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(this) {
// all function code
}
}
}
Synchronized static method
gleichbedeutend mit Synchronized statement
(Klasse verwenden)
class A {
public static synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(A.class) {
// all function code
}
}
}
Synchronisierte Anweisung (mit Variable)
class A {
private Object lock1 = new Object();
public void methodA() {
synchronized(lock1 ) {
// all function code
}
}
}
Für synchronized
haben wir beide Synchronized Methods
et Synchronized Statements
. Allerdings, Synchronized Methods
ist vergleichbar mit Synchronized Statements
Wir müssen also nur verstehen Synchronized Statements
.
\=> Im Grunde genommen werden wir
synchronized(object or class) { // object/class use to provides the intrinsic lock
// code
}
Hier sind 2 Gedanken, die zum Verständnis beitragen synchronized
intrinsic lock
damit verbunden.synchronized statement
erwirbt es automatisch die intrinsic lock
dafür synchronized statement's
Objekt und gibt es frei, wenn die Methode zurückkehrt. Solange ein Thread ein intrinsic lock
, KEINE anderen Thread kann die DERSELBE sperren => thread safe.\=> Wenn ein thread A
ruft auf. synchronized(this){// code 1}
=> Der gesamte Blockcode (innerhalb der Klasse), in dem die synchronized(this)
und alle synchronized normal method
(innerhalb der Klasse) ist gesperrt, weil DERSELBE abschließen. Sie wird ausgeführt nach thread A
entsperren ("// Code 1" beendet).
Dieses Verhalten ist vergleichbar mit synchronized(a variable){// code 1}
ou synchronized(class)
.
GLEICHES SCHLOSS \=> Sperre (nicht abhängig von der Methode oder den Anweisungen)
Ich bevorzuge synchronized statements
weil sie besser erweiterbar ist. Beispiel: In Zukunft muss nur noch ein Teil der Methode synchronisiert werden. Beispiel: Sie haben 2 synchronisierte Methoden und es haben keine zueinander, aber wenn ein Thread eine Methode ausführt, blockiert er die andere Methode (dies kann durch die Verwendung von synchronized(a variable)
).
Die Anwendung der synchronisierten Methode ist jedoch einfach und der Code sieht einfach aus. Für einige Klassen gibt es nur 1 synchronisierte Methode, oder alle synchronisierten Methoden in der Klasse in Bezug zueinander => wir können verwenden synchronized method
um den Code kürzer und verständlicher zu machen
(es ist nicht sehr relevant für synchronized
Es ist der Unterschied zwischen Objekt und Klasse oder nicht-statisch und statisch).
synchronized
oder normale Methode oder synchronized(this)
ou synchronized(non-static variable)
wird es auf Basis jeder Objektinstanz synchronisiert.synchronized
oder statische Methode oder synchronized(class)
ou synchronized(static variable)
wird auf Basis der Klasse synchronisierthttps://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Ich hoffe, es hilft
Hier ist eine Erklärung von Die Java-Tutorials .
Betrachten Sie den folgenden Code:
public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }
wenn
count
ist eine Instanz vonSynchronizedCounter
dann hat die Synchronisierung dieser Methoden zwei Auswirkungen:
- Erstens ist es nicht möglich, dass sich zwei Aufrufe von synchronisierten Methoden für dasselbe Objekt überschneiden. Wenn ein Thread eine synchronisierte Methode für ein Objekt ausführt, blockieren alle anderen Threads, die synchronisierte Methoden für dasselbe Objekt aufrufen, die Ausführung, bis der erste Thread mit dem Objekt fertig ist.
- Zweitens: Wenn eine synchronisierte Methode beendet wird, stellt sie automatisch eine "happens-before"-Beziehung zu jedem nachfolgenden Aufruf einer synchronisierten Methode für dasselbe Objekt her. Dies garantiert, dass Änderungen am Zustand des Objekts für alle Threads sichtbar sind.
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?