421 Stimmen

Gibt es einen Vorteil, eine synchronisierte Methode anstelle eines synchronisierten Blocks zu verwenden?

Kann mir jemand den Vorteil einer synchronisierten Methode gegenüber einem synchronisierten Block anhand eines Beispiels erläutern?

5voto

Søren Boisen Punkte 1548

Wichtiger Hinweis zur Verwendung des synchronisierten Blocks: Passen Sie auf, was Sie als Lock-Objekt verwenden!

Der obige Codeschnipsel von user2277816 veranschaulicht dies, indem ein Verweis auf ein Stringliteral als Sperrobjekt verwendet wird. Wenn man sich vergegenwärtigt, dass Stringliterale in Java automatisch interniert werden, wird das Problem deutlich: Jeder Code, der sich mit dem Literal "lock" synchronisiert, teilt sich dieselbe Sperre! Dies kann leicht zu Deadlocks mit völlig unverbundenen Teilen des Codes führen.

Es sind nicht nur String-Objekte, mit denen Sie vorsichtig umgehen müssen. Boxed Primitives sind ebenfalls eine Gefahr, da Autoboxing und die valueOf-Methoden dieselben Objekte je nach Wert wiederverwenden können.

Für weitere Informationen siehe: https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Nicht+synchronisieren+auf+Objekte+die+wieder+verwendet+werden+können

5voto

Maxim Shoustin Punkte 77794

Oft ist die Verwendung eines Schlosses auf einer Methodenebene zu unhöflich. Warum sollte man einen Teil des Codes sperren, der auf keine gemeinsamen Ressourcen zugreift, indem man eine ganze Methode sperrt? Da jedes Objekt eine Sperre hat, können Sie Dummy-Objekte erstellen, um die Synchronisierung auf Blockebene zu implementieren. Die Blockebene ist effizienter, da sie nicht die gesamte Methode sperrt.

Hier einige Beispiele

Methode Ebene

class MethodLevel {

  //shared among threads
SharedResource x, y ;

public void synchronized method1() {
   //multiple threads can't access
}
public void synchronized method2() {
  //multiple threads can't access
}

 public void method3() {
  //not synchronized
  //multiple threads can access
 }
}

Blockebene

class BlockLevel {
  //shared among threads
  SharedResource x, y ;

  //dummy objects for locking
  Object xLock = new Object();
  Object yLock = new Object();

    public void method1() {
     synchronized(xLock){
    //access x here. thread safe
    }

    //do something here but don't use SharedResource x, y
    // because will not be thread-safe
     synchronized(xLock) {
       synchronized(yLock) {
      //access x,y here. thread safe
      }
     }

     //do something here but don't use SharedResource x, y
     //because will not be thread-safe
    }//end of method1
 }

[Bearbeiten]

Für Collection wie Vector y Hashtable sie synchronisiert werden, wenn ArrayList o HashMap sind nicht und Sie müssen das Schlüsselwort synchronized setzen oder die Methode Collections synchronized aufrufen:

Map myMap = Collections.synchronizedMap (myMap); // single lock for the entire map
List myList = Collections.synchronizedList (myList); // single lock for the entire list

5voto

Ravindra babu Punkte 45577

Der einzige Unterschied: synchronisierte Blöcke ermöglichen im Gegensatz zu synchronisierten Methoden granulare Sperren

Grundsätzlich synchronized Block oder Methoden wurden verwendet, um thread-sicheren Code zu schreiben, indem Speicherinkonsistenzfehler vermieden werden.

Diese Frage ist sehr alt und in den letzten 7 Jahren hat sich vieles geändert. Es wurden neue Programmierkonstrukte für die Threadsicherheit eingeführt.

Sie können Thread-Sicherheit erreichen, indem Sie die erweiterte Gleichzeitigkeits-API anstelle von synchronied Blöcke. Diese Dokumentation Seite bietet gute Programmierkonstrukte, um Threadsicherheit zu erreichen.

Objekte sperren unterstützen Locking Idioms, die viele nebenläufige Anwendungen vereinfachen.

Testamentsvollstrecker definieren eine High-Level-API zum Starten und Verwalten von Threads. Executor-Implementierungen, die von java.util.concurrent bereitgestellt werden, bieten eine Thread-Pool-Verwaltung, die für umfangreiche Anwendungen geeignet ist.

Gleichzeitige Sammlungen erleichtern die Verwaltung großer Datensammlungen und können den Bedarf an Synchronisierung erheblich reduzieren.

Atomare Variablen haben Funktionen, die die Synchronisierung minimieren und helfen, Speicherkonsistenzfehler zu vermeiden.

ThreadLocalRandom (in JDK 7) ermöglicht die effiziente Erzeugung von Pseudozufallszahlen aus mehreren Threads.

Ein besserer Ersatz für synchronisiert ist ReentrantLock , die die Lock API

Eine reentrante gegenseitige Ausschlusssperre mit demselben grundlegenden Verhalten und derselben Semantik wie die implizite Monitorsperre, auf die mit synchronisierten Methoden und Anweisungen zugegriffen wird, jedoch mit erweiterten Fähigkeiten.

Beispiel mit Schlössern:

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

Siehe java.util.concurrent y java.util.concurrent.atomic Pakete auch für andere Programmierkonstrukte.

Siehe auch diese verwandte Frage:

Synchronisierung vs. Sperre

4voto

kishore Punkte 41

Die synchronisierte Methode wird zum Sperren aller Objekte verwendet Der synchronisierte Block wird zum Sperren eines bestimmten Objekts verwendet

3voto

Alex Miller Punkte 67243

Im Allgemeinen sind diese größtenteils gleich, abgesehen davon, dass der Monitor des Objekts, der verwendet wird, explizit ist, im Gegensatz zu dem impliziten this object. Ein Nachteil von synchronisierten Methoden, der meiner Meinung nach manchmal übersehen wird, ist, dass bei der Verwendung der "this"-Referenz zum Synchronisieren die Möglichkeit besteht, dass externe Objekte dasselbe Objekt sperren. Das kann ein sehr subtiler Fehler sein, wenn Sie darauf stoßen. Die Synchronisierung auf ein internes explizites Objekt oder ein anderes vorhandenes Feld kann dieses Problem vermeiden, indem die Synchronisierung vollständig gekapselt wird.

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