Frage Was bedeutet synchronisiert?


Ich habe einige Fragen bezüglich der Verwendung und Bedeutung der synchronized Stichwort.

  • Was ist die Bedeutung der synchronized Stichwort?
  • Wann sollten Methoden sein? synchronized?
  • Was bedeutet es programmatisch und logisch?

818
2017-07-06 06:47


Ursprung


Antworten:


Das synchronized Das Schlüsselwort dreht sich um verschiedene Threads, die dieselben Variablen, Objekte und Ressourcen lesen und schreiben. Dies ist kein einfaches Thema in Java, aber hier ist ein Zitat von Sun:

synchronized Methoden ermöglichen ein einfaches   Strategie zur Verhinderung von Thread   Interferenz und Speicherkonsistenz   Fehler: wenn ein Objekt sichtbar ist   mehr als ein Thread, alle liest oder   schreibt auf die Variablen dieses Objekts   getan durch synchronisierte Methoden.

In sehr, sehr kleiner Nuss: Wenn Sie zwei Threads haben, die auf dieselbe "Ressource" lesen und schreiben, sagen Sie eine Variable namens foomüssen Sie sicherstellen, dass diese Threads auf die Variable auf atomare Weise zugreifen. Ohne das synchronized Keyword, Ihr Thread 1 möglicherweise nicht den Änderungsthread 2 an angezeigt foooder schlimmer noch, es kann nur halb geändert werden. Dies wäre nicht das, was Sie logisch erwarten.

Auch dies ist ein nicht-triviales Thema in Java. Um mehr zu erfahren, erkunde Themen hier auf SO und den Interwebs über:

Erkunden Sie diese Themen bis zum Namen "Brian Goetz" wird dauerhaft mit dem Begriff verbunden "Nebenläufigkeit" in deinem Gehirn.


749
2017-07-06 07:01



Nun, ich denke wir haben genug von theoretischen Erklärungen, also bedenkt 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);
    }
}

Hinweis: synchronized blockiert den Aufruf des nächsten Threads an method test (), solange die Ausführung des vorherigen Threads noch nicht abgeschlossen ist. Threads können einzeln auf diese Methode zugreifen. Ohne synchronized Alle Threads können gleichzeitig auf diese Methode zugreifen.

Wenn ein Thread die synchronisierte Methode 'test' des Objekts aufruft (hier ist das Objekt eine Instanz der Klasse 'TheDemo'), erhält er die Sperre dieses Objekts. Jeder neue Thread kann keine synchronisierte Methode des gleichen Objekts aufrufen, solange der vorherige Thread vorhanden ist Wer das Schloss erworben hat, gibt das Schloss nicht frei.

Ähnliches passiert, wenn eine statische synchronisierte Methode der Klasse aufgerufen wird. Der Thread erwirbt die mit der Klasse verknüpfte Sperre (in diesem Fall kann jede nicht statische synchronisierte Methode einer Instanz dieser Klasse von einem beliebigen Thread aufgerufen werden, da diese 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 aktuell hält.

Ausgabe mit synchronisiert

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 synchronisiert

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

244
2018-05-15 13:23



Das synchronized Schlüsselwort verhindert den gleichzeitigen Zugriff auf einen Block von Code oder Objekt durch mehrere Threads. Standardmäßig a Hashtable ist synchronized, sodass nur ein Thread gleichzeitig auf die Tabelle zugreifen kann.

Bei der Verwendung von non-synchronized konstruiert wie HashMapSie müssen Thread-Sicherheitsfunktionen in Ihrem Code erstellen, um Speicherkonsistenzfehler zu vermeiden.


102
2018-01-22 18:39



synchronizedbedeutet, dass in einer Umgebung mit mehreren Threads ein Objekt mit synchronized Methode (s) / Block (s) lässt nicht zwei Threads auf die zugreifen synchronized Methode (n) / Block (e) des Codes gleichzeitig. 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 abgeschlossen hat. Der Overhead ist Geschwindigkeit, aber der Vorteil ist die Konsistenz der Daten gewährleistet.

Wenn Ihre Anwendung jedoch single-threaded ist, synchronized Blöcke bietet keine Vorteile.


73
2018-01-22 18:39



Das synchronized Schlüsselwort bewirkt, dass ein Thread beim Eingeben der Methode eine Sperre erhält, sodass nur ein Thread die Methode gleichzeitig ausführen kann (für die angegebene Objektinstanz, es sei denn, es handelt sich um eine statische Methode).

Dies wird häufig als "threadsicher" bezeichnet, aber ich würde sagen, dass dies ein Euphemismus ist. Obwohl es stimmt, dass die Synchronisierung den internen Zustand des Vektors vor einer Beschädigung schützt, hilft dies dem Benutzer von Vector normalerweise nicht viel.

Bedenken Sie:

 if (vector.isEmpty()){
     vector.add(data);
 }

Obwohl die beteiligten Methoden synchronisiert sind, weil sie einzeln gesperrt und entsperrt werden, können zwei unglücklich festgelegte Threads einen Vektor mit zwei Elementen erstellen.

In der Tat müssen Sie auch in Ihrem Anwendungscode synchronisieren.

Da die Synchronisierung auf Methodenebene a) teuer ist, wenn Sie sie nicht benötigen, und b) nicht ausreicht, wenn Sie eine Synchronisierung benötigen, gibt es jetzt nicht synchronisierte Ersetzungen (ArrayList im Fall von Vector).

In jüngerer Zeit wurde das Concurrency-Paket veröffentlicht, mit einer Reihe von cleveren Dienstprogrammen, die sich um Multithreading-Probleme kümmern.


50
2017-07-06 07:09



Überblick

Synchronized Schlüsselwort in Java hat mit Thread-Sicherheit zu tun, das heißt, wenn mehrere Threads die gleiche 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 synchronisierte Schlüsselwort wird verwendet, um einen Codeblock zu definieren, in dem mehrere Threads auf dieselbe Variable auf sichere Weise zugreifen können.

Tiefer

Syntax-weise die synchronized Schlüsselwort braucht ein Object als sein Parameter (genannt ein Sperrobjekt), gefolgt von a { block of code }.

  • Wenn die Ausführung auf dieses Schlüsselwort stößt, versucht der aktuelle Thread, "zu sperren / zu erwerben / zu besitzen" Objekt sperren und Ausführen des zugehörigen Codeblocks, nachdem die Sperre erlangt wurde.

  • Alle Schreibvorgänge auf Variablen innerhalb des synchronisierten Codeblocks sind garantiert für jeden anderen Thread sichtbar, der ähnlich Code in einem synchronisierten Codeblock ausführt, der denselben verwendet Objekt sperren.

  • Nur jeweils ein Thread kann die Sperre halten, währenddessen alle anderen Threads dasselbe versuchen Objekt sperren wird warten (pausieren Sie ihre Ausführung). Die Sperre wird aufgehoben, wenn die Ausführung den synchronisierten Codeblock verlässt.

Synchronisierte Methoden:

Hinzufügen synchronized Das Schlüsselwort für eine Methodendefinition ist gleich dem gesamten Methodenkörper, der in einen synchronisierten Codeblock mit dem Wrapper eingeschlossen wird Objekt sperrenSein this  (zum Beispiel Methoden) und ClassInQuestion.getClass()  (für Klassenmethoden).

- Instanzmethode ist eine Methode, die nicht hat static Stichwort.
- Klassenmethode ist eine Methode, die hat static Stichwort.

Technisch

Ohne Synchronisation ist es nicht garantiert, in welcher Reihenfolge die Lese- und Schreibvorgänge stattfinden, wobei die Variable möglicherweise mit Müll verlassen wird.
(Zum Beispiel könnte eine Variable mit der Hälfte der von einem Thread geschriebenen Bits und der Hälfte der von einem anderen Thread geschriebenen Bits enden und die Variable in einem Zustand belassen, in dem keiner der Threads zu schreiben versuchte, sondern ein gemischtes Chaos von beiden.)

Es ist nicht genug, eine Schreiboperation in einem Thread zu beenden, bevor (Wanduhrzeit) ein anderer Thread es liest, weil Hardware den Wert der Variablen zwischengespeichert haben könnte, und der Lese-Thread würde den zwischengespeicherten Wert statt dessen sehen, in was geschrieben wurde es.

Fazit

In Java müssen Sie also dem Java-Speichermodell folgen, um sicherzustellen, dass Threading-Fehler nicht auftreten.
Mit anderen Worten: Verwenden Sie Synchronisation, atomare Operationen oder Klassen, die sie für Sie unter den Hauben verwenden.

Quellen

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Java Sprachspezifikation, 2015-02-13


20
2018-06-22 15:19



Betrachten Sie es als eine Art Drehkreuz, wie Sie es auf einem Fußballplatz finden. Es gibt parallele Menschenströme, die hinein wollen, aber am Drehkreuz sind sie "synchronisiert". Es kann immer nur eine Person durchkommen. Alle, die durchkommen wollen, werden es tun, aber sie müssen vielleicht warten, bis sie durchkommen können.


18
2017-07-06 07:09