webentwicklung-frage-antwort-db.com.de

Java-synchronisierte statische Methoden: Sperre für Objekt oder Klasse

In den Java-Tutorials heißt es: "Es ist nicht möglich, dass zwei Aufrufe synchronisierter Methoden für dasselbe Objekt verschachtelt werden." 

Was bedeutet das für eine statische Methode? Wird bei einer statischen Methode kein Objekt zugeordnet, sperrt das synchronisierte Schlüsselwort statt des Objekts die Klasse?

141
jbu

Da einer statischen Methode kein Objekt zugeordnet ist, sperrt das synchronisierte Schlüsselwort für die Klasse anstelle des Objekts?

Ja. :) 

123
OscarRyz

Um Oskars (erfreulich kurz gefasst!) Ein wenig Detail hinzuzufügen, ist der relevante Abschnitt der Java-Sprachspezifikation 8.4.3.6, 'synchronized Methods' :

Eine synchronisierte Methode erwirbt einen Monitor (§17.1), bevor sie ausgeführt wird. Für eine Klassenmethode (statisch) wird der Monitor verwendet, der dem Klassenobjekt für die Klasse der Methode zugeordnet ist. Bei einer Instanzmethode wird der damit verknüpfte Monitor (das Objekt, für das die Methode aufgerufen wurde) verwendet. 

197
Cowan

Ein Punkt, auf den Sie achten sollten (mehrere Programmierer fallen normalerweise in diese Falle) ist, dass es keine Verbindung zwischen synchronisierten statischen Methoden und synchronisierten nicht statischen Methoden gibt, dh

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

Main:

A a = new A();

Faden 1:

A.f();

Faden 2:

a.g();

f () und g() sind nicht miteinander synchronisiert und können daher gleichzeitig ausgeführt werden.

79
jfpoilpret

Es sei denn, Sie implementieren g() wie folgt:

g() {
    synchronized(getClass()) {
        ...
    }
}

Ich finde dieses Muster auch nützlich, wenn ich den gegenseitigen Ausschluss zwischen verschiedenen Instanzen des Objekts implementieren möchte (was beispielsweise beim Zugriff auf eine externe Ressource erforderlich ist).

13
user267405

Schauen Sie sich die Oracle-Dokumentationsseite auf Intrinsic Locks and Synchronization an

Sie fragen sich vielleicht, was passiert, wenn eine statisch synchronisierte Methode aufgerufen wird, da eine statische Methode einer Klasse und nicht einem Objekt zugeordnet ist. In diesem Fall erhält der Thread die intrinsische Sperre für das Klassenobjekt, das der Klasse zugeordnet ist. Der Zugriff auf die statischen Felder der Klasse wird daher durch eine Sperre gesteuert, die sich von der Sperre für jede Instanz der Klasse unterscheidet.

3
Ravindra babu

Die folgenden Beispiele geben mehr Klarheit zwischen Klassen- und Objektsperren. Das folgende Beispiel wird auch anderen helfen :)

Zum Beispiel haben wir die folgenden Methoden: eine Klasse erwerben und eine andere Objektsperre übernehmen:

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

Nun können wir folgende Szenarien haben:

  1. Wenn Threads, die same Object verwenden, versucht, gleichzeitig auf die objLock- ODERstaticLock-Methode zuzugreifen (d. H. Beide Threads versuchen auf dieselbe Methode zuzugreifen)

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  2. Wenn Threads, die same Object verwenden, versucht, gleichzeitig auf staticLock- und objLock-Methoden zuzugreifen (versucht, auf andere Methoden zuzugreifen)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
  3. Wenn Threads, die different Object verwenden, versucht, auf die staticLock-Methode zuzugreifen

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  4. Wenn Threads, die different Object verwenden, versucht, auf die objLock-Methode zuzugreifen

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
2
Ravi

Eine statische Methode hat auch ein zugeordnetes Objekt. Es gehört zur Class.class-Datei im JDK-Toolkit. Wenn die .class-Datei in den RAM geladen wird, erstellt die Class.class-Instanz eine Instanz, die als Vorlagenobjekt bezeichnet wird.

ZB: - wenn Sie versuchen, ein Objekt aus einer vorhandenen Kundenklasse zu erstellen, z

Customer c = new Customer();

Die Customer.class wird in den RAM geladen. In diesem Moment erstellt Class.class in JDK-Toolkit ein Objekt namens Template-Objekt und lädt diese Customer.class in dieses Template-Objekt. Statische Member dieser Customer.class werden zu Attributen und Methoden in diesem Template-Objekt.

Eine statische Methode oder ein Attribut hat also auch ein Objekt

Für diejenigen, die keine vertraute statisch synchronisierte Methode haben, die für ein Klassenobjekt gesperrt ist, z. Für die Zeichenfolgenklasse wird dessen String.class verwendet, während die von der Instanz synchronisierte Methode die aktuelle Instanz von Object sperrt, die in Java mit dem Schlüsselwort "this" gekennzeichnet ist. Da beide Objekte unterschiedlich sind, verfügen sie über unterschiedliche Sperren. Während ein Thread statisch synchronisierte Methoden ausführt, muss ein anderer Thread in Java nicht auf die Rückkehr dieses Threads warten statisch synchronisierte Methode. 

0
Pragya