1122 Stimmen

Was bedeutet "synchronisiert"?

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?

19 Stimmen

1 Stimmen

Hilfreiche Diskussion zwischen hashmap und hashtable und Synchronisierung: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable

2 Stimmen

32voto

Gima Punkte 1752

Übersicht

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.

Tiefer

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.

Synchronisierte Methoden:

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.

Technisch

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.

Schlussfolgerung

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

22voto

paul Punkte 13038

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.

15voto

Ravindra babu Punkte 45577

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 :

Vermeiden Sie synchronized(this) in Java?

14voto

Linh Punkte 49889

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

  • Jedes Objekt/jede Klasse hat eine intrinsic lock damit verbunden.
  • Wenn ein Thread eine 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)

Synchronisierte Methode oder synchronisierte Anweisungen verwenden?

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

Hinweis

(es ist nicht sehr relevant für synchronized Es ist der Unterschied zwischen Objekt und Klasse oder nicht-statisch und statisch).

  • Wenn Sie synchronized oder normale Methode oder synchronized(this) ou synchronized(non-static variable) wird es auf Basis jeder Objektinstanz synchronisiert.
  • Wenn Sie synchronized oder statische Methode oder synchronized(class) ou synchronized(static variable) wird auf Basis der Klasse synchronisiert

Referenz

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Ich hoffe, es hilft

11voto

Shahryar Saljoughi Punkte 2159

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 von SynchronizedCounter 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.com

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.

Powered by:

X