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

969voto

Stu Thompson Punkte 37628

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.

331voto

Dheeraj Sachan Punkte 3885

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

123voto

jmort253 Punkte 33083

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.

88voto

Codemwnci Punkte 52604

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.

55voto

Thilo Punkte 248982

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.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